HH的项链

Posted lcan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HH的项链相关的知识,希望对你有一定的参考价值。

技术分享图片

 

这道题在线不好做,但是可以离线......

就是把所有的询问都读进来,按照r排序,

扫描原序列,并且记录这种颜色上一次出现的位置,

这样每次add(i,1) add(last[val[i]],-1)  (last[val[i]]!=0)

如果是一个询问的左端点,就利用树状数组的前缀和进行统计

 

这道题不好做的地方就在于一个颜色重复出现多次不好用前缀和计算,而一个同样的颜色如果在右边出现了,左边的可以不计,这就是这个解法的开始,

很巧妙啊......

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 const int maxn=1000119;
 8 int n,m;
 9 int val[maxn],last[maxn],c[maxn];
10 int ans[maxn];
11 struct Node{
12   int l,r,id,ans;
13 }node[maxn];
14 bool cmp(Node a,Node b){
15   return a.r<b.r;
16 }
17 bool cm(Node a,Node b){
18   return a.id<b.id;
19 }
20 int lowbit(int x){
21   return x&(-x);
22 }
23 int sum(int x){
24   int ret=0;
25   for(int i=x;i>0;i-=lowbit(i)) ret+=c[i];
26   return ret; 
27 }
28 void add(int pos,int val){
29   for(int i=pos;i<=n;i+=lowbit(i)) c[i]+=val;
30 }
31 int main(){
32   cin>>n;
33   for(int i=1;i<=n;i++) cin>>val[i];
34   cin>>m;
35   for(int i=1;i<=m;i++){
36     int l,r;cin>>l>>r;
37     node[i].l=l;node[i].r=r;node[i].id=i;
38   }
39   sort(node+1,node+m+1,cmp);
40   int j=1;
41   for(int i=1;i<=n;i++){
42       if(last[val[i]]!=0) add(last[val[i]],-1);
43     add(i,1);
44     while(i==node[j].r){
45       node[j].ans=sum(node[j].r)-sum(node[j].l-1);
46       j++;
47     }
48     last[val[i]]=i;
49   }
50   sort(node+1,node+m+1,cm);
51   for(int i=1;i<=m;i++) cout<<node[i].ans<<endl;
52 } 

 

以上是关于HH的项链的主要内容,如果未能解决你的问题,请参考以下文章

[SDOI2009]HH的项链

BZOJ1878: [SDOI2009]HH的项链 (主席树)

[SDOI2009]HH的项链

[SDOI2009]HH的项链

luogu1972:HH的项链

P1972 [SDOI2009]HH的项链