command_block @ 2018-10-27 16:39:10
#include<algorithm>
#include<cstdio>
using namespace std;
int n,m,last,l,r,ans,BS,maxx,
x[50500],t[50500],
p[205][205],cnt[205][50500],
o[50500];
//cnt[i][j] 类似前缀和,在前i个个块中j(离散化后)出现了几次。
//表示第i个块到第j个块的(最小的)众数。
//快速读入 O(玄学)
inline int read()
{
int X=0;char ch=0,w=0;
while(ch<'0'||ch>'9'){w|=ch=='-';ch=getchar();}
while(ch>47&&ch<58)X=X*10+(ch^48),ch=getchar();
return w?-X:X;
}
//迭代开方
int sqrt(int num)
{
int tmp=100;
tmp=(num/tmp+tmp)/2;
tmp=(num/tmp+tmp)/2;
tmp=(num/tmp+tmp)/2;
tmp=(num/tmp+tmp)/2;
tmp=(num/tmp+tmp)/2;
return tmp;
}
int main()
{
// freopen("asasa.txt","w",stdout);
// freopen("ex_4.in","r",stdin);
n=read();m=read();
// BS=max(10,min(sqrt(n),n/105));//空间上的问题,至多分成100块
BS=1000;
for (int i=0;i<n;++i)
{x[i]=read();t[i]=x[i];}
sort(t,t+n);
for (int i=0;i<n;++i)
x[i]=lower_bound(t,t+n,x[i])-t;
for (int i=0;i<n;++i)cnt[i/BS][x[i]]++;
for (int i=0;i<=(n-1)/BS;++i)
for (int j=0;j<n;++j)
cnt[i][j]+=cnt[i-1][j];
for (int i=0,tmp;i<=n/BS;++i){
maxx=-1;tmp=10000000;
for (int j=i;j<=n/BS;++j){
for (int k=i*BS;k<j*BS+BS;++k){
o[x[k]]++;
if (o[x[k]]>maxx||(o[x[k]]==maxx&&x[k]<tmp)){
maxx=o[x[k]];
tmp=x[k];
}
}p[i][j]=tmp;
}for (int j=0;j<n;++j)o[j]=0;
}
//--------输入+离散化+预处理--------
for (int i=0;i<m;i++){
l=read();r=read();
l=(l+last-1)%n;
r=(r+last-1)%n;
if(l>r)swap(l,r);
// printf("%d %d ",l,r);*/
int bl=l!=0?(l-1)/BS+1:0,br=(r+1)/BS-1,tl=bl*BS,tr=br*BS+BS;
ans=-100;maxx=-1;
if(br-bl<=2){
for (int j=l;j<=r;++j)o[x[j]]=0;
for (int j=l,tmp;j<=r;++j){
tmp=x[j];
if (++o[tmp]>maxx||(maxx==o[tmp]&&tmp<ans))
{maxx=o[tmp];ans=tmp;}
}
}else{
for (int j=l;j<tl;++j)
o[x[j]]=cnt[br][x[j]]-cnt[bl-1][x[j]];
for (int j=tr;j<=r;++j)
o[x[j]]=cnt[br][x[j]]-cnt[bl-1][x[j]];
int tmp=p[bl][br];
o[tmp]=cnt[br][tmp]-cnt[bl-1][tmp];
if (o[tmp]>maxx||(maxx==o[tmp]&&tmp<ans))
{maxx=o[tmp];ans=tmp;}
for (int j=l;j<tl;++j){
tmp=x[j];
if (++o[tmp]>maxx||(maxx==o[tmp]&&tmp<ans))
{maxx=o[tmp];ans=tmp;}
}for (int j=tr;j<=r;++j){
tmp=x[j];
if (++o[tmp]>maxx||(maxx==o[tmp]&&tmp<ans))
{maxx=o[tmp];ans=tmp;}
}
}printf("%d\n",t[ans]);
last=t[ans];
}return 0;
}
做法详见题解第一篇。
(分块从0开始)
by xenonex @ 2018-10-27 16:45:11
前排%FFT大佬orz
by Arashi丶 @ 2018-10-27 16:52:31
迭代开方精度不够吧....
by command_block @ 2018-10-27 17:43:18
没用过迭代开方。。。
by command_block @ 2018-11-03 10:54:10
问题已解决