Leo_LeLe @ 2023-07-19 21:32:22
就要吃调代码的苦!
思路:cnt[i][j]: 前i个块,j的出现次数
var[i][j]: i->j,众数
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 2e5+10,B = 320;
int beg[maxn],n,m,a[maxn],las = 0,l,r;
int sa[maxn],cnt[maxn/B][maxn],pot[maxn];
int var[maxn/B][maxn/B],tot;
struct Ans {
int val,cnt;
bool operator<(Ans a) const {
return a.cnt == cnt ? val > a.val : cnt < a.cnt;
}
};
void init() {
for(int i=1; i<=tot; ++i) {
Ans ans {0,0};
memset(pot+1,0,n<<4);
for(int j=i; j<=tot; ++j) {
for(int k=(i-1)*B+1; k<=min(j*B,n); ++k) {
ans=max(ans,Ans {a[k],++pot[a[k]]});
}
var[i][j] = ans.val;
}
}
memset(pot+1,0,n<<4);
for(int i = 1; i<=tot; ++i) {
for(int j = (i-1) * B + 1; j<=min(i*B,n); ++j) {
++pot[a[j]];
}
memcpy(cnt[i]+1,pot+1,n<<4);
}
}
int get(int l,int r) {
int li=(l-1)/B+1,ri=(r-1)/B+1;
if(li==ri) {
Ans ans {0,0};
for(int i=l; i<=r; ++i)pot[a[i]]=0;
for(int i=l; i<=r; ++i)++pot[a[i]];
for(int i=l; i<=r; ++i)ans=max(ans, {a[i],pot[a[i]]});
return ans.val;
}
Ans ans {0,0};
for(int i=l; i<=li*B; ++i)pot[a[i]]=0;
for(int i=1+(ri-1)*B; i<=r; ++i)pot[a[i]]=0;
pot[var[li+1][ri-1]]=cnt[ri-1][var[li+1][ri-1]]-cnt[li][var[li+1][ri-1]];
int sb = var[li+1][ri-1];
for(int i=l; i<=li*B; ++i)pot[a[i]]++;
for(int i=1+(ri-1)*B; i<=r; ++i)pot[a[i]]++;
for(int i=l; i<=li*B; ++i)
if(a[i]!=sb)
ans=max(ans,
{a[i],pot[a[i]]+cnt[ri-1][a[i]]-cnt[li][a[i]]});
for(int i=1+(ri-1)*B; i<=r; ++i)
if(a[i]!=sb)
ans=max(ans,
{a[i],pot[a[i]]+cnt[ri-1][a[i]]-cnt[li][a[i]]});
if(sb) ans=max(ans, {sb,pot[sb]});
return ans.val;
}
signed main() {
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
ios::sync_with_stdio(0),cin.tie(0);
cin>>n>>m;
tot=n/B+!!(n%B);
for(int i=1; i<=n; ++i)cin>>a[i];
memcpy(sa+1,a+1,n << 4);
sort(sa+1,sa+n+1);
for(int i=1; i<=n; ++i)a[i]=lower_bound(sa+1,sa+n+1,a[i])-sa;
init();
while(m--) {
cin>>l>>r;
l=(l+las-1)%n+1,r=(r+las-1)%n+1;
if(l>r)swap(l,r);
cout<<(las=sa[get(l,r)])<<'\n';
}
}
WA 20pts