[BZOJ1878][SDOI2009]HH的项链 莫队

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1878

不带修改的莫队,用一个桶记录一下当前区间中每种颜色的数量就可以做到$O(1)$更新了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 int inline readint(){
 7     int Num;char ch;
 8     while((ch=getchar())<'0'||ch>'9');Num=ch-'0';
 9     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
10     return Num;
11 }
12 void outint(int x){
13     if(x>=10) outint(x/10);
14     putchar(x%10+'0');
15 }
16 int N,M,blk;
17 int a[50010];
18 struct Query{
19     int l,r,p,id;
20     bool operator < (const Query &_)const{
21         return p!=_.p?p<_.p:r<_.r;
22     }
23 }q[200010];
24 int Ans[200010],Tans=0;
25 int c[1000010];
26 void Upd(int x,int d){
27     if(d==1){
28         if(!c[a[x]]) Tans++;
29         c[a[x]]++;
30     }
31     else{
32         if(c[a[x]]==1) Tans--;
33         c[a[x]]--;
34     }
35 }
36 int main(){
37     N=readint();
38     blk=ceil(sqrt(N));
39     for(int i=1;i<=N;i++) a[i]=readint();
40     M=readint();
41     for(int i=1;i<=M;i++){
42         q[i].l=readint();
43         q[i].r=readint();
44         q[i].p=(q[i].l-1)/blk+1;
45         q[i].id=i;
46     }
47     sort(q+1,q+1+M);
48     int l=1,r=0;
49     for(int i=1;i<=M;i++){
50         for(;r<q[i].r;r++) Upd(r+1,1);
51         for(;r>q[i].r;r--) Upd(r,-1);
52         for(;l>q[i].l;l--) Upd(l-1,1);
53         for(;l<q[i].l;l++) Upd(l,-1);
54         Ans[q[i].id]=Tans;
55     }
56     for(int i=1;i<=M;i++){
57         outint(Ans[i]);
58         putchar('\n');
59     }
60     return 0;
61 }

 

posted @ 2017-09-28 19:10  halfrot  阅读(112)  评论(0编辑  收藏  举报