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 }

 

posted @ 2017-03-01 07:16  ws_ccd  阅读(147)  评论(0编辑  收藏  举报