Luogu P4168 [Violet]蒲公英
Luogu P4168(分块)
看到数据范围
因为
将区间拆分成为
首先我们需要维护
对于每一次查询,如果
注意在数据离散之后使用离散后的数据,分清楚此时的数据是否已经离散化,避免因非数据结构本身问题导致的过长调试时间。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof(a));
using namespace std;
int read()
{
int k=0,flag=1;char b=getchar();
while (b<'0' || b>'9') {flag=(b=='-')?-1:1;b=getchar();}
while (b>='0' && b<='9') {k=(k<<3)+(k<<1)+(b^48);b=getchar();}
return k*flag;
}
const int _SIZE=4e4;
int n,m;
int len,sum,cnt;
int a[_SIZE+5],b[_SIZE+5];
int val[_SIZE+5],pos[_SIZE+5];
int s[205][_SIZE+5],f[205][205],t[_SIZE+5];
struct BLOCK{
int l,r;
}block[205];
void PreWork()
{
len=sqrt(n);
sort(b+1,b+n+1);
sum=unique(b+1,b+n+1)-b-1;
cnt=(n-1)/len+1;
for (int i=1;i<=n;i++)
val[i]=lower_bound(b+1,b+sum+1,a[i])-b;
for (int i=1;i<=cnt;i++)
{
block[i].l=(i-1)*len+1;
block[i].r=min(n,i*len);
}
for (int i=1;i<=cnt;i++)
{
for (int j=block[i].l;j<=block[i].r;j++)
s[i][val[j]]++,pos[j]=i;
for (int j=1;j<=sum;j++)
s[i][j]+=s[i-1][j];
}
for (int i=1;i<=cnt;i++)
for (int j=i;j<=cnt;j++)
{
int most=f[i][j-1];
for (int k=block[j].l;k<=block[j].r;k++)
{
int appear=s[j][val[k]]-s[i-1][val[k]],mostAppear=s[j][most]-s[i-1][most];
//printf("%d~%d %d:%d\n",block[i].l,block[j].r,b[val[k]],appear);
if (appear>mostAppear || (appear==mostAppear && val[k]<most))
most=val[k];
}
f[i][j]=most;
}
}
int query(int l,int r)
{
int most=0;
if (l>r) swap(l,r);
if (pos[r]-pos[l]<=1)
{
for (int i=l;i<=r;i++)
t[val[i]]++;
for (int i=l;i<=r;i++)
if (t[val[i]]>t[most] || (t[val[i]]==t[most] && val[i]<most))
most=val[i];
}
else
{
for (int i=l;i<=block[pos[l]].r;i++)
t[val[i]]++;
for (int i=block[pos[r]].l;i<=r;i++)
t[val[i]]++;
most=f[pos[l]+1][pos[r]-1];
for (int i=l;i<=block[pos[l]].r;i++)
{
int mostAppear=s[pos[r]-1][most]-s[pos[l]][most]+t[most];
int currAppear=s[pos[r]-1][val[i]]-s[pos[l]][val[i]]+t[val[i]];
if (currAppear>mostAppear || (currAppear==mostAppear && val[i]<most))
most=val[i];
}
for (int i=block[pos[r]].l;i<=r;i++)
{
int mostAppear=s[pos[r]-1][most]-s[pos[l]][most]+t[most];
int currAppear=s[pos[r]-1][val[i]]-s[pos[l]][val[i]]+t[val[i]];
if (currAppear>mostAppear || (currAppear==mostAppear && val[i]<most))
most=val[i];
}
}
mem(t,0);
return b[most];
}
int main()
{
//freopen("P4168.in","r",stdin);
n=read(),m=read();
for (int i=1;i<=n;i++) a[i]=b[i]=read();
PreWork();
//for (int i=1;i<=cnt;i++) {printf("1~%d ",block[i].r);for (int j=1;j<=sum;j++){printf("%d:%d | ",b[j],s[i][j]);}puts("");}
//for (int i=1;i<=cnt;i++) printf("%d~%d %d\n",block[i].l,block[i].r,b[f[i][i]]);
int x=0;
while (m--)
{
int l=read(),r=read();
l=(l+x-1)%n+1,r=(r+x-1)%n+1;
x=query(l,r);
printf("%d\n",x);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步