Beispiel #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");
    }
Beispiel #2
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");
    }
Beispiel #3
0
    void Calc()
    {
        int N = int.Parse(Console.ReadLine());

        int[]    p   = new int[N];
        int[]    rp  = new int[N];
        int[]    q   = new int[N];
        string[] str = Console.ReadLine().Split(' ');
        for (int i = 0; i < N; i++)
        {
            p[i] = int.Parse(str[i]) - 1;
            rp[int.Parse(str[i]) - 1] = i;
        }
        SegTree Seg1 = new SegTree(N / 2, this, true);

        for (int i = N - 2; i >= 0; i--)
        {
            if (i >= Seg1.segf)
            {
                Seg1.X[i] = p[Seg1.ToPoint(i) * 2];
            }
            else
            {
                int sl = i * 2 + 1;
                int sr = i * 2 + 2;
                Seg1.X[i] = Math.Min(Seg1.X[sl], Seg1.X[sr]);
            }
        }
        SegTree Seg2 = new SegTree(N / 2, this, false);

        for (int i = N - 2; i >= 0; i--)
        {
            if (i >= Seg2.segf)
            {
                Seg2.X[i] = p[Seg2.ToPoint(i) * 2 + 1];
            }
            else
            {
                int sl = i * 2 + 1;
                int sr = i * 2 + 2;
                Seg2.X[i] = Math.Min(Seg2.X[sl], Seg2.X[sr]);
            }
        }
        Heap H = new Heap(N);
        {
            int min1 = rp[Seg1.Min(0, N - 1)];
            int min2 = rp[Seg2.Min(min1 + 1, N - 1)];
            H.push(new Data(0, N - 1, min1, min2, p[min1]));
            Seg1.Delete(min1);
            Seg2.Delete(min2);
        }
        int pointer = 0;

        while (pointer < N)
        {
            Data D = H.pop();
            q[pointer]     = p[D.fp] + 1;
            q[pointer + 1] = p[D.sp] + 1;
            pointer       += 2;
            if (D.fp != D.f)
            {
                int min1;
                int min2;
                if (D.f % 2 == 0)
                {
                    min1 = rp[Seg1.Min(D.f, D.fp - 1)];
                    min2 = rp[Seg2.Min(min1 + 1, D.fp - 1)];
                    Seg1.Delete(min1);
                    Seg2.Delete(min2);
                }
                else
                {
                    min1 = rp[Seg2.Min(D.f, D.fp - 1)];
                    min2 = rp[Seg1.Min(min1 + 1, D.fp - 1)];
                    Seg2.Delete(min1);
                    Seg1.Delete(min2);
                }
                H.push(new Data(D.f, D.fp - 1, min1, min2, p[min1]));
            }
            if (D.sp != D.l)
            {
                int min1;
                int min2;
                if ((D.sp + 1) % 2 == 0)
                {
                    min1 = rp[Seg1.Min(D.sp + 1, D.l)];
                    min2 = rp[Seg2.Min(min1 + 1, D.l)];
                    Seg1.Delete(min1);
                    Seg2.Delete(min2);
                }
                else
                {
                    min1 = rp[Seg2.Min(D.sp + 1, D.l)];
                    min2 = rp[Seg1.Min(min1 + 1, D.l)];
                    Seg2.Delete(min1);
                    Seg1.Delete(min2);
                }
                H.push(new Data(D.sp + 1, D.l, min1, min2, p[min1]));
            }
            if (D.fp + 1 != D.sp)
            {
                int min1;
                int min2;
                if ((D.fp + 1) % 2 == 0)
                {
                    min1 = rp[Seg1.Min(D.fp + 1, D.sp - 1)];
                    min2 = rp[Seg2.Min(min1 + 1, D.sp - 1)];
                    Seg1.Delete(min1);
                    Seg2.Delete(min2);
                }
                else
                {
                    min1 = rp[Seg2.Min(D.fp + 1, D.sp - 1)];
                    min2 = rp[Seg1.Min(min1 + 1, D.sp - 1)];
                    Seg2.Delete(min1);
                    Seg1.Delete(min2);
                }
                H.push(new Data(D.fp + 1, D.sp - 1, min1, min2, p[min1]));
            }
        }
        for (int i = 0; i < N; i++)
        {
            sb.Append(q[i]);
            if (i == N - 1)
            {
                sb.Append("\n");
            }
            else
            {
                sb.Append(" ");
            }
        }
    }
Beispiel #4
0
    void Calc()
    {
        string[] str = Console.ReadLine().Split(' ');
        int      N   = int.Parse(str[0]) + 1;
        int      Q   = int.Parse(str[1]);
        int      A   = int.Parse(str[2]);
        int      B   = int.Parse(str[3]);

        str = Console.ReadLine().Split(' ');
        SegTree SegM = new SegTree(N, this);
        SegTree SegP = new SegTree(N, this);

        {
            int q0 = int.Parse(str[0]);
            for (int i = 2 * N - 2; i >= 0; i--)
            {
                if (i >= SegM.segf)
                {
                    if (SegM.ToPoint(i) == A)
                    {
                        SegM.X[i] = Math.Max(q0 - B, B - q0) - SegM.ToPoint(i);
                    }
                    else if (SegM.ToPoint(i) == B)
                    {
                        SegM.X[i] = Math.Max(q0 - A, A - q0) - SegM.ToPoint(i);
                    }
                    else
                    {
                        SegM.X[i] = Define.INF;
                    }
                }
                else
                {
                    int sl = i * 2 + 1;
                    int sr = i * 2 + 2;
                    SegM.X[i] = Math.Min(SegM.X[sl], SegM.X[sr]);
                }
            }
            for (int i = 2 * N - 2; i >= 0; i--)
            {
                if (i >= SegP.segf)
                {
                    if (SegP.ToPoint(i) == A)
                    {
                        SegP.X[i] = Math.Max(q0 - B, B - q0) + SegP.ToPoint(i);
                    }
                    else if (SegM.ToPoint(i) == B)
                    {
                        SegP.X[i] = Math.Max(q0 - A, A - q0) + SegP.ToPoint(i);
                    }
                    else
                    {
                        SegP.X[i] = Define.INF;
                    }
                }
                else
                {
                    int sl = i * 2 + 1;
                    int sr = i * 2 + 2;
                    SegP.X[i] = Math.Min(SegP.X[sl], SegP.X[sr]);
                }
            }
        }
        for (int i = 1; i < Q; i++)
        {
            int  qb = int.Parse(str[i - 1]);
            int  q  = int.Parse(str[i]);
            long V  = Math.Min(SegP.GetMin(q, N - 1) - q, SegM.GetMin(0, q) + q);
            SegP.AllAdd(Math.Max(qb - q, q - qb));
            SegP.Insert(qb, V + qb);
            SegM.AllAdd(Math.Max(qb - q, q - qb));
            SegM.Insert(qb, V - qb);
        }
        long count = Define.INF;

        for (int i = 0; i < N; i++)
        {
            count = Math.Min(count, SegP.X[SegP.ToLeaf(i)] - i);
        }
        count += SegP.L;
        sb.Append(count + "\n");
    }