首页 写随笔

cdcq(本博客废弃!现用博客:https://www.cnblogs.com/cdcq/)

本博客废弃!现用博客:https://www.cnblogs.com/cdcq/

导航

【BZOJ1878】【SDOI2009】 HH的项链

莫队模板题,比较简单

原题:

HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此, 他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解 决这个问题。

 N ≤ 50000,M ≤ 200000

 

莫队模板题

计算贡献的方法就是记一个cnt[i]表示值为i的有几个,每次扩张给cnt[i]+1或-1,当cnt[i]由0变成1或由1变成0时给答案+1或-1就行了

莫队框架不难(就是个按块排序然后左右扩张),关键点就在于如何O(1)计算贡献

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<vector>
 7 using namespace std;
 8 int rd(){int z=0,mk=1;  char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
11     return z*mk;
12 }
13 struct dcd{int l,r,id;}b[210000];
14 int n,m,a[51000];  int blck;
15 int cnt[1100000];
16 int ans[210000];
17 int mdf(int x,int y){
18     if(y==1)  return ++cnt[x]==1?1:0;
19     else  return --cnt[x]==0?-1:0;
20 }
21 bool cmp(dcd x,dcd y){  return (x.l/blck==y.l/blck)?(x.r<y.r):(x.l/blck<y.l/blck);}
22 int main(){//freopen("ddd.in","r",stdin);
23     cin>>n;  blck=(int)sqrt(n*1.0);
24     for(int i=1;i<=n;++i)  a[i]=rd();
25     cin>>m;
26     for(int i=1;i<=m;++i)  b[i].l=rd(),b[i].r=rd(),b[i].id=i;
27     sort(b+1,b+m+1,cmp);
28     int l=1,r=0,bwl=0;
29     for(int i=1;i<=m;++i){
30         while(r<b[i].r)  bwl+=mdf(a[++r],1);
31         while(r>b[i].r)  bwl+=mdf(a[r--],-1);
32         while(l>b[i].l)  bwl+=mdf(a[--l],1);
33         while(l<b[i].l)  bwl+=mdf(a[l++],-1);
34         ans[b[i].id]=bwl;
35     }
36     for(int i=1;i<=m;++i)  printf("%d\n",ans[i]);
37     return 0;
38 }
View Code

 

posted on 2017-02-23 22:20  cdcq_old  阅读(211)  评论(0编辑  收藏  举报