P1903 [National Training Team] With Modified Mo Team

Title

Portal P1903 [National Training Team] Number of colors / maintenance queue

answer

Compared with the ordinary Mo team, there is one more time axis corresponding to the modification operation. Each query consists of a two-dimensional (l, r) (l, r)(l,r ) becomes three-dimensional(l, r, t) (l, r, t)(l,r,t ) . The basic idea is to query the firstw − 1 w-1w1 -dimensional block, so that the frontw − 1 w-1wThe value range of 1 dimension in the block is limited, so that thewwthThe w dimension is ordered within the block, and each query can be traversed in a shorter route at this time.

Specifically, in the query interval [1, N] [1,N][1,N ] is divided into blocks, withl, r, tl, r, tl,r,t is the order of the first, second, and third keywords. Set the number of queriesQQQ. ModificationsTTT andNNN is of the same magnitude, let[1, N] [1,N][1,N ] is divided intoaaa block, thenlll hasaain the blocka species,Rrr hasaain the blockType a , the total number of blocks isa 2 a^2a2 . In the same block,ttt is monotonic, then the number of times the time axis is modified at each block boundary isO (N) O(N)O ( N ) , the number of times of modification within each block isO (N) O(N)O ( N ) , the total number of modifications isO (a 2 N) O(a^2N)O ( a2 N)l, rl, rl,The difference between the maximum value and the minimum value of r in the block isO (N / a) O(N/a)O ( N / a ) , modify between blocksO (N) O(N)O ( N ) , the total number of modificationsO (N × N / a + a 2 N) O(N\times N/a+a^2N)O ( N×N/a+a2 N). By the equationN 2 / a = a 2 NN^2/a=a^2NN2/a=a2 N, the number of blocks isN 1/3 N^{1/3}N1 / 3 , block sizeN 2/3 N ^ {2/3N2/3

You can use parity sorting for optimization. The basic principle is to divide the last dimension of the block, that is, w − 1 w-1w1 dimensional, odd block towww -dimensional ascending sort, even-numbered blockwwSort in descending order of w dimension, so thatwwThe number of times that the w -dimension is modified between adjacent blocks is greatly reduced.

#include <bits/stdc++.h>
using namespace std;
const int maxn = 133335, maxc = 1000005;
int N, M, qn, rn, res, id[maxn], col[maxn], rec[maxn], cnt[maxc];
struct P1
{
    
    
    int l, r, t, k;
    bool operator<(const P1 &b) const
    {
    
    
        if (id[l] != id[b.l])
            return l < b.l;
        if (id[r] != id[b.r])
            return r < b.r;
        return (id[r] & 1) ? t < b.t : t > b.t;
    }
} Q[maxn];
struct P2
{
    
    
    int k, c;
} R[maxn];

inline int read()
{
    
    
    int x = 0;
    char c = 0;
    for (; c < '0' || c > '9'; c = getchar())
        ;
    for (; c >= '0' && c <= '9'; c = getchar())
        x = (x << 1) + (x << 3) + c - '0';
    return x;
}

inline void add(int i)
{
    
    
    if (!cnt[col[i]]++)
        ++res;
}

inline void del(int i)
{
    
    
    if (!--cnt[col[i]])
        --res;
}

inline void upd(int t, int i)
{
    
    
    int p = R[t].k;
    if (Q[i].l <= p && p <= Q[i].r)
        del(p), swap(col[p], R[t].c), add(p);
    else
        swap(col[p], R[t].c);
}

int main()
{
    
    
    N = read(), M = read();
    for (int i = 1; i <= N; ++i)
        col[i] = read();
    for (int i = 1; i <= M; ++i)
    {
    
    
        char op;
        scanf(" %c", &op);
        if (op == 'Q')
            Q[++qn] = P1{
    
    read(), read(), rn, qn};
        else
            R[++rn] = P2{
    
    read(), read()};
    }
    int w = pow(N, 2.0 / 3.0), t = ceil((double)N / w);
    for (int i = 1; i <= t; ++i)
        for (int l = (i - 1) * w + 1, r = min(i * w, N), j = l; j <= r; ++j)
            id[j] = i;
    sort(Q + 1, Q + qn + 1);
    for (int i = 1, l = Q[1].l, r = l - 1, t = 0, ql, qr, qt; i <= qn; ++i)
    {
    
    
        ql = Q[i].l, qr = Q[i].r, qt = Q[i].t;
        while (l < ql)
            del(l++);
        while (l > ql)
            add(--l);
        while (r < qr)
            add(++r);
        while (r > qr)
            del(r--);
        while (t < qt)
            upd(++t, i);
        while (t > qt)
            upd(t--, i);
        rec[Q[i].k] = res;
    }
    for (int i = 1; i <= qn; ++i)
        printf("%d\n", rec[i]);
    return 0;
}

Guess you like

Origin blog.csdn.net/neweryyy/article/details/114435096