「国家集训队」数颜色

「国家集训队」数颜色

传送门
带修莫队板子题。
没什么好说的。。。
参考代码:

#include <algorithm>
#include <cstdio>
#include <cmath>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while ('0' > c || c > '9') f |= c == '-', c = getchar();
    while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
    s = f ? -s : s;
}

const int _ = 133333 + 10, __ = 1000010;

int n, m, gap, pos[_], ans, a[_], res[_], cnt[__];
int Cnum; struct Change{ int p, v; }C[_];
int Qnum; struct Query{ int l, r, pre, id; }Q[_];
inline bool cmp(const Query& x, const Query& y) {
    if (pos[x.l] != pos[y.l]) return pos[x.l] < pos[y.l];
    if (pos[x.r] != pos[y.r]) return pos[x.r] < pos[y.r];
    return x.pre < y.pre;
}

inline void work(int now, int i) {
    if (Q[i].l <= C[now].p && C[now].p <= Q[i].r)
        ans -= !--cnt[a[C[now].p]], ans += !cnt[C[now].v]++;
    swap(C[now].v, a[C[now].p]);
}

int main() {
#ifndef ONLINE_JUDGE
    file("cpp");
#endif
    read(n), read(m), gap = pow(n, 2.0 / 3.0);
    for (rg int i = 1; i <= n; ++i) read(a[i]), pos[i] = (i - 1) / gap + 1;
    for (rg int i = 1; i <= m; ++i) {
        char s[5]; scanf("%s", s);
        if (s[0] == 'R')
            read(C[++Cnum].p), read(C[Cnum].v);
        else
            read(Q[++Qnum].l), read(Q[Qnum].r), Q[Qnum].pre = Cnum, Q[Qnum].id = Qnum;
    }
    sort(Q + 1, Q + Qnum + 1, cmp);
    int l = 1, r = 0, now = 0;
    for (rg int i = 1; i <= Qnum; ++i) {
        while (l < Q[i].l) ans -= !--cnt[a[l++]];
        while (l > Q[i].l) ans += !cnt[a[--l]]++;
        while (r < Q[i].r) ans += !cnt[a[++r]]++;
        while (r > Q[i].r) ans -= !--cnt[a[r--]];
        while (now < Q[i].pre) work(++now, i);
        while (now > Q[i].pre) work(now--, i);
        res[Q[i].id] = ans;
    }
    for (rg int i = 1; i <= Qnum; ++i) printf("%d\n", res[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zsbzsb/p/12231569.html