分块傻逼题。
memset很慢的。。。而且其实也没有用。。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define maxn 10050 #define maxm 1000500 using namespace std; int n,m,col[maxn],pre[maxn],last[maxm],b[maxm],pos[maxn],len,num; int x,y; char s[5]; void reset(int x) { int l=(x-1)*len+1,r=min(x*len,n); for (int i=l;i<=r;i++) b[i]=pre[i]; sort(b+l,b+r+1); } void build() { if (n%len==0) num=n/len; else num=n/len+1; for (int i=1;i<=num;i++) reset(i); } void change() { scanf("%d%d",&x,&y); for(int i=1;i<=n;i++) last[col[i]]=0; col[x]=y; for (int i=1;i<=n;i++) { int regis=pre[i]; pre[i]=last[col[i]];last[col[i]]=i; if (regis!=pre[i]) reset(pos[i]); } } int find(int pos,int x) { int l=(pos-1)*len+1,r=min(pos*len,n); int re=l; while (l<=r) { int mid=(l+r)>>1; if (b[mid]<x) l=mid+1; else r=mid-1; } return l-re; } void ask() { scanf("%d%d",&x,&y); int ans=0; if (pos[x]==pos[y]) { for (int i=x;i<=y;i++) if (pre[i]<x) ans++; } else { for (int i=x;i<=pos[x]*len;i++) if (pre[i]<x) ans++; for (int i=(pos[y]-1)*len+1;i<=y;i++) if (pre[i]<x) ans++; for (int i=pos[x]+1;i<=pos[y]-1;i++) ans+=find(i,x); } printf("%d\n",ans); } int main() { scanf("%d%d",&n,&m); len=int(sqrt(n)+log(2*n)/log(2)); for (int i=1;i<=n;i++) { scanf("%d",&col[i]); pre[i]=last[col[i]]; last[col[i]]=i; pos[i]=(i-1)/len+1; } build(); for (int i=1;i<=m;i++) { scanf("%s",s); if (s[0]=='Q') ask(); else change(); } return 0; }