[SDOI2009][bzoj1878] HH的项链 [莫队模板题]

题面:

传送门

思路:

就是一道莫队的模板题目......

开一个1000000的数组记录每个数出现的次数,然后每次从1到0或者从0到1更新答案

莫队讲解看这里:莫队

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],curl,curr,block,ans[200010];
17 struct query{
18     int l,r,i;
19 }a[200010];
20 bool cmp(query l,query r){
21     if(l.l/block!=r.l/block) return (l.l/block)<(r.l/block);
22     else return l.r<r.r;
23 }
24 void add(int i){
25     cnt[x[i]]++;if(cnt[x[i]]==1) tot++;
26     //cout<<"add "<<i<<" "<<x[i]<<" "<<cnt[x[i]]<<"\n";
27 }
28 void erase(int i){
29     cnt[x[i]]--;if(!cnt[x[i]]) tot--;
30     //cout<<"erase "<<i<<" "<<x[i]<<" "<<cnt[x[i]]<<"\n";
31 }
32 int main(){
33     //freopen("diff.in","r",stdin);
34     //freopen("diff.out","w",stdout);
35     int i;
36     n=read();for(i=1;i<=n;i++) x[i]=read();block=sqrt(n);
37     //cout<<"input one complete "<<n<<" "<<i<<"\n";
38     m=read();for(i=1;i<=m;i++) a[i].l=read(),a[i].r=read(),a[i].i=i;
39     //cout<<"input two complete "<<m<<" "<<i<<"\n";
40     sort(a+1,a+m+1,cmp);curl=a[1].l;curr=a[1].r;
41     for(i=a[1].l;i<=a[1].r;i++) add(i);
42     ans[a[1].i]=tot;
43     for(i=2;i<=m;i++){
44         while(curl<a[i].l) erase(curl++);
45         while(curl>a[i].l) add(--curl);
46         while(curr<a[i].r) add(++curr);
47         while(curr>a[i].r) erase(curr--);
48         ans[a[i].i]=tot;
49         //cout<<"now "<<curl<<" "<<curr<<"\n";
50     }
51     for(i=1;i<=m;i++) printf("%d\n",ans[i]);
52 }
53 

 

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