コード例 #1
0
    void Calc()
    {
        string S = re.s();
        int    N = S.Length;

        int[] C = new int[26];
        for (int i = 0; i < N; i++)
        {
            C[S[i] - 'a']++;
        }
        int odd = 0;

        for (int i = 0; i < 26; i++)
        {
            if (C[i] % 2 == 1)
            {
                odd++;
            }
        }
        if (odd > 1 || (odd == 1 && N % 2 == 0))
        {
            sb.Append(-1 + "\n");
            return;
        }
        List <int>[] G = new List <int> [26];
        for (int i = 0; i < 26; i++)
        {
            G[i] = new List <int>();
        }
        int[] order = new int[N];
        for (int i = 0; i < N; i++)
        {
            order[i] = G[S[i] - 'a'].Count;
            G[S[i] - 'a'].Add(i);
        }
        SegTree Seg = new SegTree(N, this);

        for (int i = 2 * N - 2; i >= 0; i--)
        {
            if (i >= Seg.segf)
            {
                Seg.X[i] = 1;
            }
            else
            {
                int sl = i * 2 + 1;
                int sr = i * 2 + 2;
                Seg.X[i] = Seg.X[sl] + Seg.X[sr];
            }
        }
        long count  = 0;
        bool center = false;

        for (int i = 0; i < N; i++)
        {
            if (order[i] * 2 + 1 < C[S[i] - 'a'])
            {
                int pair = G[S[i] - 'a'][C[S[i] - 'a'] - 1 - order[i]];
                if (pair != N - 1)
                {
                    count += Seg.Sum(pair + 1, N - 1);
                }
                Seg.Delete(pair);
                if (center)
                {
                    count++;
                }
            }
            else if (order[i] * 2 + 1 == C[S[i] - 'a'])
            {
                center = true;
            }
        }
        sb.Append(count + "\n");
    }
コード例 #2
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(" ");
            }
        }
    }