块大小取n2/3优于取sqrt(n)的情况,总体复杂度O(n5/3)。
大小为pow(n t,1/3) 时间复杂度pow(n n* n *n *t,1/3)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e4+100;
int a[N];
struct query{
int id,l,r,t;
}q[N];
struct modify{
int p,c;
}d[N];
int cnt[1000010];
int ans[N];
int len;
int get(int x)
{
return x/len;
}
bool cmp(query a,query b)
{
int i=get(a.l),j=get(b.l),x=get(a.r),y=get(b.r);
if(i!=j) return i<j;
if(x!=y) return x<y;
return a.t<b.t;
}
void add(int x,int &res)
{
if(cnt[x]==0) res++;
cnt[x]++;
}
void del(int x,int &res)
{
cnt[x]--;
if(cnt[x]==0) res--;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int cq=0,cd=0;
for(int i=1;i<=m;i++)
{
char op[2];
scanf("%s",op);
if(op[0]=='Q')
{
++cq;
scanf("%d%d",&q[cq].l,&q[cq].r);
q[cq].id=cq;//id是cq不是i
q[cq].t=cd;
}
else
{
++cd;
scanf("%d%d",&d[cd].p,&d[cd].c);
}
}
len=pow((double)(n*cd),1.0/3.0)+1;//算出来可能为0
sort(q+1,q+cq+1,cmp);
for(int k=1,i=0,j=1,ct=0,res=0;k<=cq;k++)
{
int id=q[k].id,l=q[k].l,r=q[k].r,t=q[k].t;
while(j<l) del(a[j++],res);
while(j>l) add(a[--j],res);
while(i<r) add(a[++i],res);
while(i>r) del(a[i--],res);
while(ct<t)
{
++ct;
if(d[ct].p>=l&&d[ct].p<=r)
{
del(a[d[ct].p],res);
add(d[ct].c,res);
}
swap(a[d[ct].p],d[ct].c);
}
while(ct>t)
{
if(d[ct].p>=l&&d[ct].p<=r)
{
del(a[d[ct].p],res);
add(d[ct].c,res);
}
swap(a[d[ct].p],d[ct].c);
ct--;
}
ans[id]=res;
}
for(int i=1;i<=cq;i++)
{
printf("%d\n",ans[i]);
}
}