带修莫队
- 修改记录时间,修改值,修改后值 同时读入修改时进行修改,修改结束后还原
const int maxn = 2e6 + 7;
int n, t, qn, m, k, a[maxn], ans[maxn], num[maxn], sum;
char op;
struct query {
int l, r, t, id;
} q[maxn];
struct change {
int pl, val, oval;
} chg[maxn];
bool cmp(query a, query b) {
if (a.l / k != b.l / k) return a.l / k < b.l / k;
if (a.r / k != b.r / k) return a.r / k < b.r / k;
return a.t < b.t;
}
void add(int x) {
if (x == 0)
return;
num[x]++;
sum += (num[x] == 1);
}
void del(int x) {
if (x == 0)
return;
num[x]--;
sum -= (num[x] == 0);
}
int l = 1, r = 0, tn = 0;
void addchange(int t) {
int pl = chg[t].pl, val = chg[t].val;
if (pl >= l && pl <= r)
add(val), del(a[pl]);
a[pl] = val;
}
void delchange(int t) {
int pl = chg[t].pl, val = chg[t].oval;
if (pl >= l && pl <= r)
add(val), del(a[pl]);
a[pl] = val;
}
void solve() {
cin >> n >> m;
k = pow(n, 2.0 / 3);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1, l, r; i <= m; i++) {
cin >> op >> l >> r;
if (op == 'R') chg[++t].pl = l, chg[t].val = r, chg[t].oval = a[l], a[l] = r;
else q[++qn].l = l, q[qn].r = r, q[qn].t = t, q[qn].id = qn;
}
for (int i = t; i >= 1; i--) a[chg[i].pl] = chg[i].oval;
sort(q + 1, q + 1 + qn, cmp);
for (int i = 1; i <= qn; i++) {
int L = q[i].l, R = q[i].r, T = q[i].t;
while (tn < T) addchange(++tn);
while (tn > T) delchange(tn--);
while (l > L) add(a[--l]);
while (r < R) add(a[++r]);
while (l < L) del(a[l++]);
while (r > R) del(a[r--]);
ans[q[i].id] = sum;
}
for (int i = 1; i <= qn; i++)
cout << ans[i] << "\n";
}