题目:1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。
思路:带修改莫队,不修改时直接对区间维护就行,带修改时多维护一个时间变量,与不修改的莫队同样的思路。
#include<bits/stdc++.h>
using namespace std;
const int maxn=10005;
struct node1{
int l,r,id,t;
node1(){}
node1(int _l,int _r,int _id,int _t)
{
l=_l; r=_r; id=_id; t=_t;
}
}s[maxn];
int block[maxn];
bool cmp1(const node1 &a,const node1 &b)
{
if(block[a.l]==block[b.l])
{
if(a.r==b.r) return a.t<b.t;
return a.r<b.r;
}
return a.l<b.l;
}
struct node2{
int pos,la,now;
node2(){}
node2(int _pos,int _la,int _now)
{
pos=_pos; la=_la; now=_now;
}
}u[maxn];
int la[maxn];
int a[maxn],n,m,m1,m2;
int ans[maxn],c[1000010],sum,l,r,t;
void update1(int k,int v)
{
if(k>=l&&k<=r)
{
c[a[k]]--;
if(c[a[k]]==0) sum--;
a[k]=v;
c[a[k]]++;
if(c[a[k]]==1) sum++;
}
else
a[k]=v;
}
void update2(int k,int v)
{
if(c[a[k]]) sum--;
c[a[k]]+=v;
if(c[a[k]]) sum++;
}
void Modui()
{
l=1,r=0;t=0;sum=0;
for(int i=1;i<=m1;i++)
{
while(t<s[i].t)
{
t++;
update1(u[t].pos,u[t].now);
}
while(t>s[i].t)
{
update1(u[t].pos,u[t].la);
t--;
}
while(r<s[i].r)
{
r++;
update2(r,1);
}
while(r>s[i].r)
{
update2(r,-1);
r--;
}
while(l<s[i].l)
{
update2(l,-1);
l++;
}
while(l>s[i].l)
{
l--;
update2(l,1);
}
ans[s[i].id]=sum;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
la[i]=a[i];
}
m1=m2=0;
for(int i=1;i<=m;i++)
{
char ch[3];
int x,y;
scanf("%s%d%d",ch,&x,&y);
if(ch[0]=='Q')
{
m1++;
s[m1]=node1(x,y,m1,m2);
}
else
{
u[++m2]=node2(x,la[x],y);
la[x]=y;
}
}
int o=sqrt(n);
for(int i=1;i<=n;i++)
block[i]=i/o;
sort(s+1,s+m1+1,cmp1);
Modui();
for(int i=1;i<=m1;i++)
printf("%d\n",ans[i]);
return 0;
}