[国家集训队][bzoj2120] 数颜色 [带修改莫队]

题面:

传送门

思路:

这道题和SDOI2009的HH的项链很像,只是多了一个修改

模板套上去呀

莫队学习请戳这里:莫队

Code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 inline int read(){
 8     int re=0,flag=1;char ch=getchar();
 9     while(ch>'9'||ch<'0'){
10         if(ch=='-') flag=-1;
11         ch=getchar();
12     }
13     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
14     return re*flag;
15 }
16 int n,m,cnt[1000010],tot=0,x[50010],cur[50010];
17 int curl,curr,curc,block,ans[200010],cntq,cntc;
18 struct query{
19     int l,r,i,ch;
20 }a[200010];
21 struct ch{
22     int pos,to,from;
23 }c[200010];
24 bool cmp(query l,query r){
25     if(l.l/block!=r.l/block) return (l.l/block)<(r.l/block);
26     else{
27         if(l.r!=r.r) return l.r<r.r;
28         else return l.ch<r.ch;
29     }
30 }
31 void add(int i){
32     cnt[x[i]]++;if(cnt[x[i]]==1) tot++;
33     //cout<<"add "<<i<<" "<<x[i]<<" "<<cnt[x[i]]<<" "<<tot<<"\n";
34 }
35 void erase(int i){
36     cnt[x[i]]--;if(!cnt[x[i]]) tot--;
37     //cout<<"erase "<<i<<" "<<x[i]<<" "<<cnt[x[i]]<<" "<<tot<<"\n";
38 }
39 void change(int l,int r,int i){
40     //cout<<"***change "<<l<<" "<<r<<" "<<i<<" "<<x[c[i].pos]<<"\n";
41     if(l<=c[i].pos&&c[i].pos<=r) erase(c[i].pos);
42     x[c[i].pos]=c[i].to;
43     if(l<=c[i].pos&&c[i].pos<=r) add(c[i].pos);
44 }
45 void back(int l,int r,int i){
46     //cout<<"***back "<<l<<" "<<r<<" "<<i<<"\n";
47     if(l<=c[i].pos&&c[i].pos<=r) erase(c[i].pos);
48     x[c[i].pos]=c[i].from;
49     if(l<=c[i].pos&&c[i].pos<=r) add(c[i].pos);
50 }
51 int main(){
52     // freopen("testdata.in","r",stdin);
53     int i,t1,t2;char s[10];
54     n=read();m=read();
55     for(i=1;i<=n;i++) x[i]=cur[i]=read();
56     for(i=1;i<=m;i++){
57         scanf("%s",s);t1=read();t2=read();
58         if(s[0]=='Q')
59             a[++cntq].l=t1,a[cntq].r=t2,a[cntq].i=cntq,a[cntq].ch=cntc;
60         else
61             c[++cntc].pos=t1,c[cntc].from=cur[t1],cur[t1]=c[cntc].to=t2;
62     }
63     block=sqrt(n);
64     sort(a+1,a+cntq+1,cmp);
65      
66     curl=a[1].l;curr=a[1].r;
67     for(i=a[1].l;i<=a[1].r;i++) add(i);
68     while(curc<a[1].ch) change(a[1].l,a[1].r,++curc);
69     ans[a[1].i]=tot;
70  
71     for(i=2;i<=m;i++){
72         while(curl<a[i].l) erase(curl++);
73         while(curl>a[i].l) add(--curl);
74         while(curr<a[i].r) add(++curr);
75         while(curr>a[i].r) erase(curr--);
76         while(curc<a[i].ch) change(a[i].l,a[i].r,++curc);
77         while(curc>a[i].ch) back(a[i].l,a[i].r,curc--);
78         ans[a[i].i]=tot;
79         //cout<<"now "<<curl<<" "<<curr<<"\n";
80     }
81     for(i=1;i<=cntq;i++) printf("%d\n",ans[i]);
82 }
83 

 

posted @ 2018-03-04 08:59  dedicatus545  阅读(246)  评论(0编辑  收藏  举报