巴蜀3540 -- Violet 6 最终话蒲公英
Posted SilverNebula
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了巴蜀3540 -- Violet 6 最终话蒲公英相关的知识,希望对你有一定的参考价值。
Description
原题的时间限制是 2s .
亲爱的哥哥:
你在那个城市里面过得好吗?
我在家里面最近很开心呢。昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了。我觉得把那么可怕的怪物召唤出来的那个坏蛋也很坏呢。不过奶奶说他是很难受的时候才做出这样的事的……
最近村子里长出了一大片一大片的蒲公英。一刮风,这些蒲公英就能飘到好远的地方了呢。我觉得要是它们能飘到那个城市里面,让哥哥看看就好了呢!
哥哥你要快点回来哦!
Azure 读完这封信之后微笑了一下。
“蒲公英吗……”
在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。
为了简化起见,我们把所有的蒲公英看成一个长度为 n 的序列 (a1, a2, a3, ..., an),其中 ai 为一个正整数,表示第 i 棵蒲公英的种类编号。
而每次询问一个区间[l, r],你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。
注意,你的算法必须是在线的。
亲爱的哥哥:
你在那个城市里面过得好吗?
我在家里面最近很开心呢。昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了。我觉得把那么可怕的怪物召唤出来的那个坏蛋也很坏呢。不过奶奶说他是很难受的时候才做出这样的事的……
最近村子里长出了一大片一大片的蒲公英。一刮风,这些蒲公英就能飘到好远的地方了呢。我觉得要是它们能飘到那个城市里面,让哥哥看看就好了呢!
哥哥你要快点回来哦!
爱你的妹妹 Violet
Azure 读完这封信之后微笑了一下。
“蒲公英吗……”
在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。
为了简化起见,我们把所有的蒲公英看成一个长度为 n 的序列 (a1, a2, a3, ..., an),其中 ai 为一个正整数,表示第 i 棵蒲公英的种类编号。
而每次询问一个区间[l, r],你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。
注意,你的算法必须是在线的。
Input
第一行两个整数 n, m,表示有 n 株蒲公英,m 次询问。
接下来一行 n 个空格分隔的整数 ai,表示蒲公英的种类。
再接下来 m 行每行两个整数 l0, r0,我们令上次询问的结果为 x(如果这是第一次询问,则 x = 0)。
令 l = (l0 + x - 1) mod n + 1, r = (r0 + x - 1) mod n + 1,如果 l > r,则交换 l, r。
最终的询问区间为[l, r]。
接下来一行 n 个空格分隔的整数 ai,表示蒲公英的种类。
再接下来 m 行每行两个整数 l0, r0,我们令上次询问的结果为 x(如果这是第一次询问,则 x = 0)。
令 l = (l0 + x - 1) mod n + 1, r = (r0 + x - 1) mod n + 1,如果 l > r,则交换 l, r。
最终的询问区间为[l, r]。
Output
输出 m 行。每行一个整数,表示每次询问的结果。
Sample Input
6 3
1 2 3 2 1 2
1 5
3 6
1 5
Sample Output
1
2
1
Hint
对于 20% 的数据,保证 1 ≤ n, m ≤ 3000 。
对于 100% 的数据,保证 1 ≤ n ≤ 40000,1 ≤ m ≤ 50000,1 ≤ ai ≤ 109 。
对于 100% 的数据,保证 1 ≤ n ≤ 40000,1 ≤ m ≤ 50000,1 ≤ ai ≤ 109 。
Source
Violet 6 最终话
区间求众数,强制在线。
分块处理,求出每一块区间的众数。对于一次询问的区间,其中众数要么是中间大块的众数,要么是两边小块中的数。
扫描所求区间中的边缘小块,求其中每个数在区间内的出现次数,找出次数最多的就是区间众数了。
求数的出现次数,可以预先用vector或者普通数组存这个数在序列中的每一个出现位置,然后二分查找即可。
不管什么算法,逢二分必挂的被动技能又强行发动了,调二分调了半小时……
用时比别人多了10000+ms,也是迷。
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 #include<map> 9 using namespace std; 10 const int mxn=50010; 11 const int block=180; 12 int read(){ 13 int x=0,f=1;char ch=getchar(); 14 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 15 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 16 return x*f; 17 } 18 int n,m; 19 // 20 vector<int>pos[mxn];//数字出现位置 21 int v[mxn];//离散化标号对应的数字 22 map<int,int>mp;int mct=0;//数字对应的离散化标号 23 // 24 int f[510][510]; 25 int b[mxn];//分块 26 // 27 int a[mxn]; 28 int cnt[mxn]; 29 void init(int x){ 30 memset(cnt,0,sizeof cnt); 31 int i,j; 32 int mx=0,num=0; 33 for(i=(x-1)*block+1;i<=n;i++){ 34 cnt[v[i]]++; 35 if(cnt[v[i]]>mx || (cnt[v[i]]==mx && a[i]<num)){ 36 mx=cnt[v[i]]; 37 num=a[i]; 38 } 39 f[x][b[i]]=num; 40 } 41 return; 42 } 43 int find(int x,int L,int R){ 44 /* x=mp[x]; 45 int t=upper_bound(pos[x].begin(),pos[x].end(),R)-lower_bound(pos[x].begin(),pos[x].end(),L); 46 return t;*/ 47 x=mp[x]; 48 int l=0,r=pos[x].size()-1; 49 int ansl,ansr; 50 while(l<=r){ 51 int mid=(l+r)>>1; 52 if(pos[x][mid]<=R)l=mid+1; 53 else r=mid-1; 54 } 55 ansr=l; 56 l=0,r=pos[x].size()-1; 57 while(l<=r){ 58 int mid=(l+r)>>1; 59 if(pos[x][mid]<L)l=mid+1; 60 else r=mid-1; 61 } 62 ansl=l; 63 // printf("ask:%d res:%d %d\n",x,ansl,ansr); 64 return ansr-ansl; 65 } 66 int query(int l,int r){ 67 int mxnum=f[b[l]+1][b[r]-1]; 68 int mx=find(mxnum,l,r); 69 int i,j; 70 int ed=min(b[l]*block,r); 71 for(i=l;i<=ed;i++){ 72 int tmp=find(a[i],l,r); 73 if(tmp>mx || (tmp==mx && a[i]<mxnum)){ 74 mx=tmp; mxnum=a[i]; 75 } 76 } 77 if(b[l]!=b[r]) 78 for(i=(b[r]-1)*block+1;i<=r;i++){ 79 int tmp=find(a[i],l,r); 80 if(tmp>mx || (tmp==mx && a[i]<mxnum)){ 81 mx=tmp; mxnum=a[i]; 82 } 83 } 84 return mxnum; 85 } 86 int main(){ 87 n=read();m=read(); 88 int i,j; 89 for(i=1;i<=n;i++){ 90 a[i]=read(); 91 if(!mp[a[i]])mp[a[i]]=++mct; 92 v[i]=mp[a[i]]; 93 pos[v[i]].push_back(i); 94 } 95 for(i=1;i<=n;++i){b[i]=(i-1)/block+1;} 96 for(i=1;i<=b[n];i++){init(i);} 97 int x=0; 98 int ql,qr; 99 while(m--){ 100 ql=read();qr=read(); 101 ql=(ql+x-1)%n+1; 102 qr=(qr+x-1)%n+1; 103 if(ql>qr)swap(ql,qr); 104 x=query(ql,qr); 105 printf("%d\n",x); 106 } 107 return 0; 108 }
以上是关于巴蜀3540 -- Violet 6 最终话蒲公英的主要内容,如果未能解决你的问题,请参考以下文章