当前位置: 代码迷 >> 综合 >> 洛谷 P4168 [Violet]蒲公英
  详细解决方案

洛谷 P4168 [Violet]蒲公英

热度:89   发布时间:2023-12-06 07:31:37.0

题目:蒲公英

思路:
分块。
把所有数分成 n \sqrt{n} n ?个块,在每个块里分别求解。

代码:

#include<bits/stdc++.h>
using namespace std;#define maxn 40000
#define maxq 200
#define read(x) scanf("%d",&x)int n,m;
int a[maxn+5];map<int,int> mp;
int dic[maxn+5],cnt;int cq,sq;int p[maxq+5][maxq+5];
int s[maxq+5][maxn+5];int vis[maxn+5];int main() {
    read(n),read(m);for(int i=1;i<=n;i++) read(a[i]);for(int i=1;i<=n;i++) mp[a[i]]++;for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it) {
    mp[it->first]=++cnt;dic[cnt]=it->first;}for(int i=1;i<=n;i++) a[i]=mp[a[i]];sq=sqrt(n),cq=n/sq+(n%sq!=0);for(int i=1;i<=cq;i++) {
    for(int j=1;j<=cnt;j++) s[i][j]=s[i-1][j];for(int j=(i-1)*sq+1;j<=min(n,i*sq);j++) {
    s[i][a[j]]++;}}for(int i=1;i<=cq;i++) {
    for(int k=(i-1)*sq+1;k<=n;k++) {
    int j=1+(k-1)/sq;if(k%sq==1) p[i][j]=p[i][j-1];vis[a[k]]++;if(vis[a[k]]>vis[p[i][j]]||(vis[a[k]]==vis[p[i][j]]&&a[k]<p[i][j])) p[i][j]=a[k];}memset(vis,0,sizeof(vis));}int lst=0;for(int i=1;i<=m;i++) {
    int x,y,l,r;read(x),read(y);x=(lst+x-1)%n+1,y=(lst+y-1)%n+1;if(x>y) swap(x,y);l=x-x%sq+sq+1;r=y-y%sq;int L=l/sq+1,R=r/sq;int t=p[L][R];if(L>R) {
    int P=0;for(int j=x;j<=y;j++) {
    vis[a[j]]++;if(vis[a[j]]>vis[P]||(a[j]<P&&vis[a[j]]==vis[P])) P=a[j];}memset(vis,0,sizeof(vis));printf("%d\n",lst=dic[P]);continue;}for(int j=x;j<l;j++) {
    s[R][a[j]]++;if(s[R][a[j]]-s[L-1][a[j]]>s[R][p[L][R]]-s[L-1][p[L][R]]||(s[R][a[j]]-s[L-1][a[j]]==s[R][p[L][R]]-s[L-1][p[L][R]]&&a[j]<p[L][R])) p[L][R]=a[j];}for(int j=r+1;j<=y;j++) {
    s[R][a[j]]++;if(s[R][a[j]]-s[L-1][a[j]]>s[R][p[L][R]]-s[L-1][p[L][R]]||(s[R][a[j]]-s[L-1][a[j]]==s[R][p[L][R]]-s[L-1][p[L][R]]&&a[j]<p[L][R])) p[L][R]=a[j];}printf("%d\n",lst=dic[p[L][R]]);for(int j=x;j<l;j++) s[R][a[j]]--;for(int j=r+1;j<=y;j++) s[R][a[j]]--;p[L][R]=t;}return 0;
}