码迷,mamicode.com
首页 > 其他好文 > 详细

HH的项链

时间:2018-11-03 17:30:49      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:技术   端点   nbsp   using   位置   sort   names   .com   bit   

技术分享图片

 

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

就是把所有的询问都读进来,按照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的项链

标签:技术   端点   nbsp   using   位置   sort   names   .com   bit   

原文地址:https://www.cnblogs.com/lcan/p/9901204.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!