分块暴力
根据询问分成修改次数+1块
每块里面不用分块直接莫队(本来想在块之间继续分块的,结果没分直接A了)
/**************************************************************
Problem: 2120
User: syh0313
Language: C++
Result: Accepted
Time:2296 ms
Memory:5484 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
using
namespace
std;
const
int
maxn=10010;
int
n,m,k,num[1000010],v[maxn],pp,cnt,cntc,pl,pr,sum,ans[maxn],p[maxn],nn;
struct
da{
int
l,r,id;}a[maxn],c[1010];
int
f[maxn];
char
s[10];
bool
cmp(da aa,da bb)
{
if
(aa.l/k==bb.l/k && !((aa.l/k)&1))
return
aa.r<bb.r;
if
(aa.l/k==bb.l/k && (aa.l/k)&1)
return
aa.r>bb.r;
return
aa.l<bb.l;
}
int
main()
{
scanf
(
"%d%d"
,&n,&m);
for
(
int
i=1;i<=n;i++)
scanf
(
"%d"
,&v[i]);
for
(
int
i=1;i<=m;i++)
{
int
x,y;
scanf
(
"%s%d%d"
,s+1,&x,&y);
if
(s[1]==
'Q'
) a[++cnt].l=x,a[cnt].r=y,a[cnt].id=cnt;
else
f[cnt+1]++,c[++cntc].l=x,c[cntc].r=y,p[++nn]=cnt+1;
}
//k=sqrt(cnt)+1e-10;
//for (int i=1;i<nn;i++) sort(a+p[i],a+p[i+1],cmp);
//if (p[1]>1) sort(a+1,a+p[1],cmp);
//if (p[nn]<=n) sort(a+p[nn],a+cnt+1,cmp);
while
(f[1]--) pp++,v[c[pp].l]=c[pp].r;
pl=a[1].l; pr=a[1].r;
for
(
int
i=pl;i<=pr;i++)
if
(++num[v[i]]==1) sum++;
ans[a[1].id]=sum;
for
(
int
i=2;i<=cnt;i++)
{
if
(f[i])
{
while
(f[i]--)
{
pp++;
int
lc=c[pp].l,xx=c[pp].r;
if
(pl>lc || pr<lc) v[lc]=xx;
else
{
if
(--num[v[lc]]==0) sum--;
if
(++num[xx]==1) sum++;
v[lc]=xx;
}
}
}
while
(pl>a[i].l) {
if
(++num[v[--pl]]==1) sum++;}
while
(pl<a[i].l) {
if
(--num[v[pl++]]==0) sum--;}
while
(pr>a[i].r) {
if
(--num[v[pr--]]==0) sum--;}
while
(pr<a[i].r) {
if
(++num[v[++pr]]==1) sum++;}
ans[a[i].id]=sum;
}
for
(
int
i=1;i<=cnt;i++)
printf
(
"%d\n"
,ans[i]);
return
0;
}