块长可能不对,就不要管了
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 9;
#define gc getchar
inline int read() {
int c = gc(), t = 1, n = 0;
while(isspace(c)) { c = gc(); }
if(c == '-') { t = -1, c = gc(); }
while(isdigit(c)) { n = n * 10 + c - '0', c = gc(); }
return n * t;
}
#undef gc
struct change {
int id,last,now;
}p[N];
struct node {
int l,r,pre,id,bl,br;
}q[N];
int n,m,tota,totb,len,l,r,t,nl,nr,nt;
int a[N],ans[N],cnt,sum[N];
char ch;
bool cmp(node u,node v) {
if(u.bl != v.bl) return u.bl < v.bl;
else {
if(u.br != v.br) return u.br < v.br;
else return u.pre < v.pre;
}
}
inline void del(int x) {
if(--sum[a[x]] == 0) --cnt;
}
inline void add(int x) {
if(++sum[a[x]] == 1) ++cnt;
}
int main() {
n = read(); m = read(); len = pow(n,2.0 / 3);
for(int i = 1;i <= n;i++) a[i] = read();
for(int i = 1;i <= m;i++) {
do ch = getchar(); while(ch != 'Q' && ch != 'R');
if(ch == 'R') {
p[++tota].id = read(); p[tota].now = read();
p[tota].last = a[p[tota].id]; a[p[tota].id] = p[tota].now;
}else {
q[++totb].id = i; q[totb].l = read(); q[totb].r = read();
q[totb].pre = tota; q[totb].bl = (q[totb].l - 1) / len + 1; q[totb].br = (q[totb].r - 1) / len + 1;
}
}
sort(q + 1,q + totb + 1,cmp);
l = 1; r = 0; t = 0; cnt = 0;
for(int i = 1;i <= m;i++) {
nl = q[i].l; nr = q[i].r; nt = q[i].pre;
while(l < nl) del(l++);
while(l > nl) add(--l);
while(r > nr) del(r--);
while(r < nr) add(++r);
while(t < nt) { // go forward
++t;
int alpha = p[t].id;
if(l <= alpha && alpha <= r) del(alpha);
a[alpha] = p[t].now;
if(l <= alpha && alpha <= r) add(alpha);
}
while(t > nt) { // go back
int alpha = p[t].id;
if(l <= alpha && alpha <= r) del(alpha);
a[alpha] = p[t].last;
if(l <= alpha && alpha <= r) add(alpha);
--t;
}
ans[q[i].id] = cnt;
}
for(int i = 1;i <= totb;i++) {
printf("%d\n",ans[i]);
}
return 0;
}