bzoj 2453: 维护队列
这不是和数颜色一个题吗???。。。
这里是用分块2333
1 #include<bits/stdc++.h> 2 #define N 100005 3 #define M 5000005 4 #define LL long long 5 #define inf 0x3f3f3f3f 6 #define lowbit(x) x&(-x) 7 using namespace std; 8 inline int ra() 9 { 10 int x=0,f=1; char ch=getchar(); 11 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 12 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 13 return x*f; 14 } 15 int n,Q,m,block; 16 int c[N],pos[N],pre[N],b[N],last[M]; 17 int find(int x, int v) 18 { 19 int l=(x-1)*block+1,r=min(n,x*block); 20 int first=l; 21 while (l<=r) 22 { 23 int mid=(l+r)>>1; 24 if (pre[mid]<v) l=mid+1; 25 else r=mid-1; 26 } 27 return l-first; 28 } 29 int ask(int l, int r) 30 { 31 int ans=0; 32 if (pos[l]==pos[r]){ 33 for (int i=l; i<=r; i++) if (b[i]<l) ans++;} 34 else 35 { 36 for (int i=l; i<=block*pos[l]; i++) if (b[i]<l) ans++; 37 for (int i=block*(pos[r]-1)+1; i<=r; i++) if (b[i]<l) ans++; 38 } 39 for (int i=pos[l]+1; i<pos[r]; i++) 40 ans+=find(i,l); 41 return ans; 42 } 43 void reset(int x) 44 { 45 int l=(x-1)*block+1,r=min(x*block,n); 46 for (int i=l; i<=r; i++) pre[i]=b[i]; 47 sort(pre+l,pre+r+1); 48 } 49 void build() 50 { 51 for (int i=1; i<=n; i++) 52 { 53 b[i]=last[c[i]]; 54 last[c[i]]=i; 55 pos[i]=(i-1)/block+1; 56 } 57 for (int i=1; i<=m; i++) reset(i); 58 } 59 void change(int x, int v) 60 { 61 for (int i=1; i<=n; i++) last[c[i]]=0; 62 c[x]=v; 63 for (int i=1; i<=n; i++) 64 { 65 int t=b[i]; 66 b[i]=last[c[i]]; 67 if (t!=b[i]) reset(pos[i]); 68 last[c[i]]=i; 69 } 70 } 71 int main() 72 { 73 n=ra(); Q=ra(); 74 for (int i=1; i<=n; i++) c[i]=ra(); 75 block=int(sqrt(n)+log(2*n)/log(2)); 76 if (n%block) m=n/block+1; else m=n/block; 77 build(); 78 while (Q--) 79 { 80 char s[5]; scanf("%s",s); int x=ra(),y=ra(); 81 if (s[0]=='Q') printf("%d\n",ask(x,y)); 82 else change(x,y); 83 } 84 return 0; 85 }