代码逻辑是用bitset维护每个块中的颜色,相当于一个桶。修改时候就把修改点的块清零,再重新建这个块的bitset。
总的时间复杂度大概是O(N∗sqrt(N))
代码如下
#include<bits/stdc++.h>
using namespace std;
#define maxn 200010
int a[maxn];
int pos[maxn];
bitset<1000000>s[550];
int n,m,bl;
inline int read()
{
int X=0; bool flag=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
inline void update(int x,int v)
{
a[x]=v;
s[pos[x]].reset();
for(int i=(pos[x]-1)*bl+1;i<=min(n,pos[x]*bl);i++)
s[pos[x]].set(a[i]);
}
inline int query(int l,int r)
{
bitset<1000000>ret;
ret.reset();
for(int i=l;i<=min(r,pos[l]*bl);i++)
ret.set(a[i]);
if(pos[l]==pos[r])
return ret.count();
for(int i=(pos[r]-1)*bl+1;i<=r;i++)
ret.set(a[i]);
for(int i=pos[l]+1;i<=pos[r]-1;i++)
ret=ret|s[i];
return ret.count();
}
int main()
{
n=read();
m=read();
bl=pow(n,1.5);
for(int i=1;i<=n;i++)
{
a[i]=read();
pos[i]=(i-1)/bl+1;
s[pos[i]].set(a[i]);
}
while(m--)
{
char op[10];
int x,y;
scanf("%s",op);
x=read();
y=read();
if(op[0]=='Q')
printf("%d\n",query(x,y));
else
update(x,y);
}
return 0;
}