35pts,求助

P4168 [Violet] 蒲公英

看看我的行不行 ``` #include <cstdio> #include <cmath> #include <algorithm> const int maxn=40000+10; int a[maxn],b[maxn],s[200+10][maxn],f[200+10][200+10],t[maxn]; int block; int read() { int x=0,p=1; char ch=getchar(); while(ch<'0'||ch>'9') { if (ch=='-') p=-1; ch=getchar(); } while('0'<=ch&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*p; } int get_block(int u) { return (u-1)/block+1; } inline int min(int x,int y) { return x<y?x:y; } int main() { int n=read(),m=read(); block=int(sqrt(n)); for (int i=1;i<=n;i++) b[i]=a[i]=read(); std::sort(b+1, b+1+n); int sum=std::unique(b+1, b+1+n)-b-1,cnt=(n-1)/block+1; for (int i=1;i<=n;i++) a[i]=std::lower_bound(b+1, b+1+sum, a[i])-b; for (int i=1;i<=cnt;i++) { for (int j=block*(i-1)+1;j<=min(block*i, n);j++) s[i][a[j]]++; 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 MAX=f[i][j-1]; for (int k=block*(j-1);k<=min(block*j, n);k++) if ((s[j][a[k]]-s[i-1][a[k]]>s[j][MAX]-s[i-1][MAX])||(s[j][a[k]]-s[i-1][a[k]]==s[j][MAX]-s[i-1][MAX]&&a[k]<MAX)) MAX=a[k]; f[i][j]=MAX; } int x=0; while(m--) { int l=(read()+x-1)%n+1,r=(read()+x-1)%n+1; if (l>r) std::swap(l, r); int bl=get_block(l),br=get_block(r),MAX=0; if (br-bl<=1)/ { for (int i=l;i<=r;i++) t[a[i]]++; for (int i=l;i<=r;i++) if (t[a[i]]>t[MAX]||(t[a[i]]==t[MAX]&&a[i]<MAX)) MAX=a[i]; for (int i=l;i<=r;i++)//将桶清空 t[a[i]]=0; } else { for (int i=l;i<=block*bl;i++) t[a[i]]++; for (int i=block*(br-1)+1;i<=r;i++) t[a[i]]++; MAX=f[bl+1][br-1]; for (int i=l;i<=block*bl;i++)//考虑蓝色部分出现的数是否会成为众数 { int pre=t[MAX]+s[br-1][MAX]-s[bl][MAX],now=t[a[i]]+s[br-1][a[i]]-s[bl][a[i]]; if (now>pre||(now==pre&&MAX>a[i])) MAX=a[i]; } for (int i=block*(br-1)+1;i<=r;i++) { int pre=t[MAX]+s[br-1][MAX]-s[bl][MAX],now=t[a[i]]+s[br-1][a[i]]-s[bl][a[i]]; if (now>pre||(now==pre&&MAX>a[i])) MAX=a[i]; } for (int i=l;i<=block*bl;i++)//将桶清空 t[a[i]]=0; for (int i=block*(br-1)+1;i<=r;i++) t[a[i]]=0; } x=b[MAX]; printf("%d\n",x); } return 0; } ```
by Cjh20120613 @ 2023-11-29 21:21:35


|