首先这题暴力可过,没事干就别写正解。。。
正解是三维带修改莫队,在普通莫队基础上再加上一个时间维,作为第三关键字参与排序,但是时间的转移十分蛋痛。。。
如果时间转移的下标在[L,R]内,就要对ans进行维护,同时对数组修改。如果不在,就只对数组修改。。。
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct hp{
int st,l,r,tim,num;
}qst[100001];
int L,R,TIM,n,m,ans=0,a[100001],b[200002],c[100001];
int num[100001],change[100001][3],size,ansi[100001];
int cmp(const hp &a,const hp &b)
{
if ((a.st<b.st)||(a.st==b.st&&a.r<b.r)||(a.st==b.st&&b.r==a.r&&a.tim<b.tim))
return 1;
else return 0;
}
void work(int i)
{
int l=qst[i].l,r=qst[i].r,tim=qst[i].tim;
if (l!=r)
{
while (L<l)
{
if (num[a[L]]==1) ans--;
num[a[L]]--;
L++;
}
while (L>l)
{
L--;
if (!num[a[L]]) ans++;
num[a[L]]++;
}
while (R<r)
{
R++;
if (!num[a[R]]) ans++;
num[a[R]]++;
}
while (R>r)
{
if (num[a[R]]==1) ans--;
num[a[R]]--;
R--;
}
}
while (tim>TIM)
{
TIM++;
if (L<=change[TIM][0]&&change[TIM][0]<=R)
{
num[change[TIM][1]]--;
if (num[change[TIM][1]]==0) ans--;
num[change[TIM][2]]++;
if (num[change[TIM][2]]==1) ans++;
}
a[change[TIM][0]]=change[TIM][2];
}
while (tim<TIM)
{
if (L<=change[TIM][0]&&change[TIM][0]<=R)
{
num[change[TIM][2]]--;
if (num[change[TIM][2]]==0) ans--;
num[change[TIM][1]]++;
if (num[change[TIM][1]]==1) ans++;
}
a[change[TIM][0]]=change[TIM][1];
TIM--;
}
if (qst[i].num) ansi[qst[i].num]=ans;
}
int main()
{
int i,per,numi=0,time=0;
char opt;
scanf("%d%d",&n,&m); per=sqrt(n);
for (i=1;i<=n;++i)
{
scanf("%d",&a[i]);
c[i]=b[i]=a[i];
}
b[0]=n;
for (i=1;i<=m;++i)
{
scanf("%c",&opt);
while (opt!='Q'&&opt!='R')
scanf("%c",&opt);
if (opt=='Q')
{
scanf("%d%d",&qst[i].l,&qst[i].r);
qst[i].st=qst[i].l/per+1;
qst[i].num=++numi; qst[i].tim=time;
}
if (opt=='R')
{
time++;
scanf("%d%d",&qst[i].l,&change[time][2]);
qst[i].r=qst[i].l; qst[i].st=qst[i].l/per+1;
qst[i].tim=time; qst[i].num=0;
change[time][0]=qst[i].l; change[time][1]=c[qst[i].l]; c[qst[i].l]=change[time][2];
b[++b[0]]=change[time][2];
}
}
sort(b+1,b+b[0]+1);
size=unique(b+1,b+b[0]+1)-b-1;
for (i=1;i<=n;++i)
a[i]=upper_bound(b+1,b+size+1,a[i])-b-1;
for (i=1;i<=time;++i)
{
change[i][1]=upper_bound(b+1,b+size+1,change[i][1])-b-1;
change[i][2]=upper_bound(b+1,b+size+1,change[i][2])-b-1;
}
sort(qst+1,qst+m+1,cmp);
L=qst[1].l; R=qst[1].r;
for (TIM=1;TIM<=qst[1].tim;++TIM)
a[change[TIM][0]]=change[TIM][2];
for (i=qst[1].l;i<=qst[1].r;++i)
{
if (num[a[i]]==0) ans++;
num[a[i]]++;
}
if (qst[1].num) ansi[qst[1].num]=ans;
TIM=qst[1].tim;
for (i=1;i<=m;++i)
work(i);
for (i=1;i<=numi;++i)
printf("%d\n",ansi[i]);
}