Пример #1
0
    void Calc()
    {
        int N = re.i();

        int[] B = re.ia();
        int   Q = re.i();

        Data[] D = new Data[Q];
        for (int i = 0; i < Q; i++)
        {
            D[i] = new Data(re.i() - 1, re.i() - 1);
        }
        Array.Sort(D, (x, y) => (x.l - y.l));
        SegTree Seg = new SegTree(N + 1, this);

        for (int i = 2 * N; i >= 0; i--)
        {
            if (i >= Seg.segf)
            {
                Seg.X[i] = Seg.ToPoint(i) == 0 ? 0 : 10000000;
            }
            else
            {
                int sl = i * 2 + 1;
                int sr = i * 2 + 2;
                Seg.X[i] = Math.Min(Seg.X[sl], Seg.X[sr]);
            }
        }
        int p = 0;

        {
            while (p < Q && D[p].l == 0)
            {
                Seg.Change(D[p].r + 1, 0);
                p++;
            }
        }
        for (int i = 0; i < N; i++)
        {
            if (i != 0)
            {
                Seg.Change(i, Seg.Min(i - 1, i));
            }
            if (B[i] == 1)
            {
                Seg.Add(i, i, 1);
            }
            else
            {
                Seg.Add(i + 1, N, 1);
            }
            while (p < Q && D[p].l == i + 1)
            {
                Seg.Change(D[p].r + 1, Seg.Min(i, D[p].r + 1));
                p++;
            }
        }
        sb.Append(Seg.Min(N - 1, N) + "\n");
    }
Пример #2
0
    void Calc()
    {
        int N = re.i();

        int[] white = new int[N];
        int[] black = new int[N];
        for (int i = 0; i < 2 * N; i++)
        {
            if (re.s() == "W")
            {
                white[re.i() - 1] = i;
            }
            else
            {
                black[re.i() - 1] = i;
            }
        }
        long[,] DP = new long[N + 1, N + 1];
        for (int i = 0; i <= N; i++)
        {
            SegTree Seg = new SegTree(2 * N, this);
            for (int j = 0; j < i; j++)
            {
                Seg.Add(white[j]);
            }
            for (int j = 0; j <= N; j++)
            {
                if (i == 0 & j == 0)
                {
                    DP[i, j] = 0;
                }
                else if (i == 0)
                {
                    DP[i, j] = DP[i, j - 1] + Seg.Sum(black[j - 1] + 1, 2 * N - 1);
                    Seg.Add(black[j - 1]);
                }
                else if (j == 0)
                {
                    DP[i, j] = DP[i - 1, j] + Seg.Sum(white[i - 1] + 1, 2 * N - 1);
                }
                else
                {
                    Seg.Add(black[j - 1]);
                    DP[i, j] = Math.Min(DP[i - 1, j] + Seg.Sum(white[i - 1] + 1, 2 * N - 1), DP[i, j - 1] + Seg.Sum(black[j - 1] + 1, 2 * N - 1));
                }
            }
        }
        sb.Append(DP[N, N] + "\n");
    }
Пример #3
0
    void Calc()
    {
        string[] str = Console.ReadLine().Split(' ');
        int      N   = int.Parse(str[0]);
        int      M   = int.Parse(str[1]);

        Data[] D = new Data[N];
        for (int i = 0; i < N; i++)
        {
            str  = Console.ReadLine().Split(' ');
            D[i] = new Data(int.Parse(str[0]), int.Parse(str[1]));
        }
        Array.Sort(D, (x, y) => (x.space - y.space));
        SegTree Seg = new SegTree(M + 1, this);
        int     p   = 0;

        for (int i = 1; i <= M; i++)
        {
            int count;
            while (p < N && D[p].space < i)
            {
                Seg.Add(D[p].l, D[p].r);
                p++;
            }
            count = N - p;
            for (int j = i; j <= M; j += i)
            {
                count += Seg.Get(j);
            }
            sb.Append(count + "\n");
        }
    }
Пример #4
0
    void Calc()
    {
        string[] str = Console.ReadLine().Split(' ');
        int      N   = int.Parse(str[0]);
        long     K   = int.Parse(str[1]);

        long[] A = new long[N];
        for (int i = 0; i < N; i++)
        {
            A[i] = int.Parse(Console.ReadLine()) - K;
        }
        N++;
        long[] sum = new long[N];
        for (int i = 1; i < N; i++)
        {
            sum[i] = sum[i - 1] + A[i - 1];
        }
        long[] B = new long[N];
        int[]  C = new int[N];
        for (int i = 0; i < N; i++)
        {
            B[i] = sum[i];
            C[i] = i;
        }
        Array.Sort(C, (x, y) => (B[x] > B[y] ? 1 : (B[x] == B[y] ? (x > y ? 1 : (x == y ? 0 : -1)) : -1)));
        SegTree Seg   = new SegTree(N, this);
        long    count = 0;

        for (int i = N - 1; i >= 0; i--)
        {
            count += Seg.Sum(C[i], N - 1);
            Seg.Add(C[i]);
        }
        sb.Append(count + "\n");
    }
Пример #5
0
    bool check(int D)
    {
        SegTree Seg = new SegTree(2 * N);

        for (int i = 0; i < N; i++)
        {
            Seg.Add(Seg.ToLeaf(Q[i]), Seg.ToLeaf(Q[i + N]), true, true);
        }
        for (int i = Seg.segf - 1; i >= 0; i--)
        {
            int sl = i * 2 + 1;
            int sr = i * 2 + 2;
            Seg.Add(i, sl, true, false);
            Seg.Add(i, sr, true, false);
        }
        for (int i = 0; i < 2 * N - 1; i++)
        {
            int Pi = P[i] >= N ? Y[P[i] - N] : X[P[i]];
            int bf = i;
            int bl = 2 * N - 1;
            while (bf != bl)
            {
                int bc = (bf + bl + 1) / 2;
                if (Pi + D > (P[bc] >= N ? Y[P[bc] - N] : X[P[bc]]))
                {
                    bf = bc;
                }
                else
                {
                    bl = bc - 1;
                }
            }
            if (bl != i)
            {
                Seg.Add(i + 1, bl, i);
            }
        }
        TwoSatSolver T = new TwoSatSolver(4 * N - 1, Seg.vs.ToArray(), Seg.us.ToArray(), Seg.vb.ToArray(), Seg.ub.ToArray());

        return(T.Answer());
    }
Пример #6
0
 public void Add(SegTree S, long M)
 {
     if (l == null && r == null)
     {
         S.Add(p, count * M % Define.mod);
     }
     if (l != null)
     {
         l.Add(S, M);
     }
     if (r != null)
     {
         r.Add(S, M);
     }
 }
Пример #7
0
    void Calc()
    {
        string[] str = Console.ReadLine().Split(' ');
        int      N   = int.Parse(str[0]);
        int      M   = int.Parse(str[1]);

        int[] L = new int[N];
        int[] R = new int[N];
        int[] C = new int[N];
        for (int i = 0; i < N; i++)
        {
            str  = Console.ReadLine().Split(' ');
            L[i] = int.Parse(str[0]);
            R[i] = int.Parse(str[1]);
            C[i] = i;
        }
        Array.Sort(C, (x, y) => (R[y] - R[x]));
        int     count = Math.Max(N - M, 0);
        SegTree Seg   = new SegTree(M + 2, this);

        for (int i = 2 * M + 2; i >= 0; i--)
        {
            if (i >= Seg.segf)
            {
                Seg.Z[i] = -Seg.ToPoint(i);
            }
            else
            {
                int sl = i * 2 + 1;
                int sr = i * 2 + 2;
                Seg.Z[i] = Math.Max(Seg.Z[sl], Seg.Z[sr]);
            }
        }
        int p = 0;

        for (int i = M; i >= 0; i--)
        {
            while (p < N && R[C[p]] >= i + 1)
            {
                Seg.Add(L[C[p]], M + 1);
                p++;
            }
            int A = Seg.Max(0, i) - (M - i);
            count = Math.Max(count, A);
        }
        sb.Append(count + "\n");
    }
Пример #8
0
 SegTree Merge(SegTree F, SegTree T)
 {
     if (F.size >= T.size)
     {
         long FT = T.AddRight(F);
         long TF = T.AddLeft(F);
         F.c1 = (F.c1 + T.c1 + FT) % Define.mod;
         F.c2 = (F.c2 + T.c2 + FT + TF) % Define.mod;
         T.Add(F);
         return(F);
     }
     else
     {
         long FT = F.AddLeft(T);
         long TF = F.AddRight(T);
         T.c1 = (F.c1 + T.c1 + FT) % Define.mod;
         T.c2 = (F.c2 + T.c2 + FT + TF) % Define.mod;
         F.Add(T);
         return(T);
     }
 }
Пример #9
0
    void Calc()
    {
        string[] str = Console.ReadLine().Split(' ');
        N   = int.Parse(str[0]);
        M   = int.Parse(str[1]);
        str = Console.ReadLine().Split(' ');
        A   = new int[N];
        for (int i = 0; i < N; i++)
        {
            A[i] = int.Parse(str[i]);
        }
        SegTree Seg = new SegTree(M + 2, this);

        for (int i = 0; i < N - 1; i++)
        {
            if (A[i] < A[i + 1])
            {
                Seg.Add(A[i] + 1, A[i + 1], A[i + 1] + 1, -1);
                Seg.Add(A[i + 1] + 1, M + 1, A[i + 1] - A[i], 0);
                Seg.Add(0, A[i], A[i + 1] - A[i], 0);
            }
            else
            {
                Seg.Add(A[i + 1] + 1, A[i], A[i + 1] - A[i] + M, 0);
                Seg.Add(A[i] + 1, M + 1, A[i + 1] + 1 + M, -1);
                Seg.Add(0, A[i + 1], A[i + 1] + 1, -1);
            }
        }
        long count = 1000000000000;

        for (int i = 1; i <= M; i++)
        {
            count = Math.Min(Seg.Get(i), count);
        }
        sb.Append(count + "\n");
    }
Пример #10
0
    void Calc()
    {
        string[] str = Console.ReadLine().Split(' ');
        int      N   = int.Parse(str[0]);
        long     K   = int.Parse(str[1]);

        long[] L   = new long[N];
        long[] R   = new long[N];
        int    eN  = 0;
        long   sum = 0;

        {
            for (int i = 0; i < N; i++)
            {
                str = Console.ReadLine().Split(' ');
                long D = int.Parse(str[0]);
                bool b = int.Parse(str[1]) == 1;
                if (b && 2 * D > K)
                {
                    sb.Append("-1\n");
                    return;
                }
                if (b)
                {
                    L[eN] = K - (((sum + 2 * D) % K) == 0 ? K : ((sum + 2 * D) % K));
                    R[eN] = K - ((sum % K) == 0 ? K : sum % K);
                    eN++;
                }
                sum += 2 * D;
            }
        }
        long[] DPL    = new long[eN];
        long[] DPR    = new long[eN];
        long[] Points = new long[2 * eN];
        int[]  A      = new int[2 * eN];
        for (int i = 0; i < eN; i++)
        {
            Points[2 * i]     = L[i];
            Points[2 * i + 1] = R[i];
            A[2 * i]          = 2 * i;
            A[2 * i + 1]      = 2 * i + 1;
        }
        Array.Sort(Points, A);
        int[] B = new int[2 * eN];
        for (int i = 0; i < 2 * eN; i++)
        {
            B[A[i]] = i;
        }
        SegTree Seg = new SegTree(2 * eN, this);

        for (int i = 4 * eN - 2; i >= 0; i--)
        {
            Seg.X[i] = eN;
        }
        for (int i = eN - 1; i >= 0; i--)
        {
            int lp = B[2 * i];
            int rp = B[2 * i + 1];
            int gL = Seg.Get(lp);
            DPL[i] = gL == eN ? 0 : DPR[gL] + (K + Points[B[2 * gL + 1]] - Points[lp]) % K;
            int gR = Seg.Get(rp);
            DPR[i] = gR == eN ? 0 : DPR[gR] + (K + Points[B[2 * gR + 1]] - Points[rp]) % K;
            int  bf = 0;
            int  bl = 2 * eN;
            long C  = Points[B[2 * i]];
            while (bf != bl)
            {
                int bc = (bf + bl) / 2;
                if (bc == 2 * eN || C < Points[bc])
                {
                    bl = bc;
                }
                else
                {
                    bf = bc + 1;
                }
            }
            int l = bf;
            bf = -1;
            bl = 2 * eN - 1;
            C  = Points[B[2 * i + 1]];
            while (bf != bl)
            {
                int bc = (bf + bl + 1) / 2;
                if (bc == -1 || C > Points[bc])
                {
                    bf = bc;
                }
                else
                {
                    bl = bc - 1;
                }
            }
            int r = bf;
            if (Points[lp] < Points[rp])
            {
                if (l <= r)
                {
                    Seg.Add(i, l, r);
                }
            }
            else
            {
                if (l != 2 * eN)
                {
                    Seg.Add(i, l, 2 * eN - 1);
                }
                if (r != -1)
                {
                    Seg.Add(i, 0, r);
                }
            }
        }
        for (int i = 4 * eN - 2; i >= 0; i--)
        {
            Seg.X[i] = eN;
        }
        long min = DPR[0];

        for (int i = 0; i < eN; i++)
        {
            int lp = B[2 * i];
            int rp = B[2 * i + 1];
            int gL = Seg.Get(lp);
            if (gL == eN)
            {
                min = Math.Min(min, DPL[i]);
            }
            int gR = Seg.Get(rp);
            if (gR == eN)
            {
                min = Math.Min(min, DPR[i]);
            }
            int  bf = 0;
            int  bl = 2 * eN;
            long C  = Points[B[2 * i]];
            while (bf != bl)
            {
                int bc = (bf + bl) / 2;
                if (bc == 2 * eN || C < Points[bc])
                {
                    bl = bc;
                }
                else
                {
                    bf = bc + 1;
                }
            }
            int l = bf;
            bf = -1;
            bl = 2 * eN - 1;
            C  = Points[B[2 * i + 1]];
            while (bf != bl)
            {
                int bc = (bf + bl + 1) / 2;
                if (bc == -1 || C > Points[bc])
                {
                    bf = bc;
                }
                else
                {
                    bl = bc - 1;
                }
            }
            int r = bf;
            if (Points[lp] < Points[rp])
            {
                if (l <= r)
                {
                    Seg.Add(0, l, r);
                }
            }
            else
            {
                if (l != 2 * eN)
                {
                    Seg.Add(0, l, 2 * eN - 1);
                }
                if (r != -1)
                {
                    Seg.Add(0, 0, r);
                }
            }
        }
        sb.Append((min + sum) + "\n");
    }
Пример #11
0
    void Calc()
    {
        string[] str = Console.ReadLine().Split(' ');
        long     x1  = int.Parse(str[0]);
        long     y1  = int.Parse(str[1]);
        long     x2  = int.Parse(str[2]);
        long     y2  = int.Parse(str[3]);
        int      N   = int.Parse(Console.ReadLine());
        double   count;

        if (x1 == x2)
        {
            bool b = false;
            for (int i = 0; i < N; i++)
            {
                str = Console.ReadLine().Split(' ');
                long X = int.Parse(str[0]);
                if (x1 == X)
                {
                    long Y = int.Parse(str[1]);
                    if (Math.Min(y1, y2) < Y && Y < Math.Max(y1, y2))
                    {
                        b = true;
                    }
                    break;
                }
            }
            count = (Math.Max(y1, y2) - Math.Min(y1, y2)) * 100 + (b ? (20 * (Math.PI / 2 - 1)) : 0);
        }
        else if (y1 == y2)
        {
            bool b = false;
            for (int i = 0; i < N; i++)
            {
                str = Console.ReadLine().Split(' ');
                long Y = int.Parse(str[1]);
                if (y1 == Y)
                {
                    long X = int.Parse(str[0]);
                    if (Math.Min(x1, x2) < X && X < Math.Max(x1, x2))
                    {
                        b = true;
                    }
                    break;
                }
            }
            count = (Math.Max(x1, x2) - Math.Min(x1, x2)) * 100 + (b ? (20 * (Math.PI / 2 - 1)) : 0);
        }
        else
        {
            long[] xp = new long[N];
            long[] yp = new long[N];
            for (int i = 0; i < N; i++)
            {
                str = Console.ReadLine().Split(' ');
                long X = int.Parse(str[0]);
                if (x1 > x2)
                {
                    X = 100000000 - 1 - X;
                }
                long Y = int.Parse(str[1]);
                if (y1 > y2)
                {
                    Y = 100000000 - 1 - Y;
                }
                xp[i] = X;
                yp[i] = Y;
            }
            if (x1 > x2)
            {
                x1 = 100000000 - 1 - x1;
                x2 = 100000000 - 1 - x2;
            }
            if (y1 > y2)
            {
                y1 = 100000000 - 1 - y1;
                y2 = 100000000 - 1 - y2;
            }
            long[]      DX;
            long[]      DY;
            Compression YC;
            {
                List <long> LX = new List <long>();
                List <long> LY = new List <long>();
                for (int i = 0; i < N; i++)
                {
                    if (x1 <= xp[i] && xp[i] <= x2 && y1 <= yp[i] && yp[i] <= y2)
                    {
                        LX.Add(xp[i]);
                        LY.Add(yp[i]);
                    }
                }
                DX = LX.ToArray();
                DY = LY.ToArray();
                YC = new Compression(LY.ToArray());
            }
            Array.Sort(DX, DY);
            if (DY.Length != 0)
            {
                bool b1 = (DY[0] == y1 && DY[DY.Length - 1] == y2);
                bool b2 = (DX[0] == x1 && DX[DX.Length - 1] == x2);
                for (int i = 1; i < DY.Length; i++)
                {
                    b2 &= DX[i] == DX[i - 1] + 1 && DY[i] > DY[i - 1];
                    b1 &= DY[i] == DY[i - 1] + 1;
                }
                SegTree Seg = new SegTree(YC.size, this);
                for (int i = 0; i < DY.Length; i++)
                {
                    int YP = YC.ToPoint(DY[i]);
                    Seg.Add(YP, Seg.Max(0, YP) + 1);
                }
                count = (y2 - y1 + x2 - x1) * 100 - (20 - 5 * Math.PI) * Seg.Max(0, YC.size - 1) + ((b1 || b2) ? 5 * Math.PI : 0);
            }
            else
            {
                count = (y2 - y1 + x2 - x1) * 100;
            }
        }
        sb.Append(count + "\n");
    }