bzoj2724: [Violet 6]蒲公英

来源:互联网 发布:逃出绝命镇 知乎 编辑:程序博客网 时间:2024/04/28 10:28

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2724

题意:中文题。。

分析:在线求区间众数,用分块预处理,详见http://www.docin.com/p-679227660.html

PS:如果加入了修改操作的话,我们将块的大小换成n^(1/3),然后每次修改完之后先暴力重构f数组,再用f数组暴力重构dp数组即可,时间复杂度为O((n+q)*n^(2/3))。

代码:

#include<map>#include<set>#include<cmath>#include<queue>#include<math.h>#include<cstdio>#include<vector>#include<string>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=40100;const int MAX=151;const int MOD=1000007;const int MOD1=100000007;const int MOD2=100000009;const int INF=1000000000;const double EPS=0.00000001;typedef long long ll;typedef unsigned long long ull;int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}struct node {    int u,v;};int k,n,m,b[N],c[N];int clo,tot,d[N],f[220][N],num[N];node a[N],dp[220][220];int cmd(node x,node y) {    return x.u<y.u;}void init() {    scanf("%d%d", &n, &m);    for (int i=1;i<=n;i++) {        scanf("%d", &a[i].u);a[i].v=i;    }    k=a[0].u=a[0].v=0;    sort(a,a+n+1,cmd);    for (int i=1;i<=n;i++)    if (a[i].u==a[i-1].u) b[a[i].v]=k;    else { b[a[i].v]=++k;c[k]=a[i].u; }}void deal() {    int i,j,h,l,r;    clo=(int)sqrt(n);tot=n/clo+1;    memset(f,0,sizeof(f));    memset(num,0,sizeof(num));    for (i=1;i<=n;i++) d[i]=(i+clo-1)/clo;    for (i=1;i<tot;i++) {        l=(i-1)*clo+1;r=i*clo;        for (j=l;j<=r;j++) num[b[j]]++;        for (j=1;j<=k;j++) f[i][j]=num[j];    }    l=(tot-1)*clo+1;r=n;    for (j=l;j<=r;j++) num[b[j]]++;    for (j=1;j<=k;j++) f[n/clo+1][j]=num[j];    for (i=1;i<=tot;i++) {        l=(i-1)*clo+1;        i==tot ? r=n:r=i*clo;        dp[i][i].u=dp[i][i].v=0;        for (j=l;j<=r;j++)        if ((f[i][b[j]]-f[i-1][b[j]]>dp[i][i].u)||(f[i][b[j]]-f[i-1][b[j]]==dp[i][i].u&&b[j]<dp[i][i].v)) {            dp[i][i].u=f[i][b[j]]-f[i-1][b[j]];dp[i][i].v=b[j];        }    }    for (i=1;i<tot;i++)        for (j=1;j<=tot;j++)        if (i+j<=tot) {            l=(i+j-1)*clo+1;            i+j==tot ? r=n:r=(i+j)*clo;            dp[j][j+i].u=dp[j][j+i-1].u;            dp[j][j+i].v=dp[j][j+i-1].v;            for (h=l;h<=r;h++) num[b[h]]=0;            for (h=l;h<=r;h++) num[b[h]]++;            for (h=l;h<=r;h++)            if ((f[j+i-1][b[h]]-f[j-1][b[h]]+num[b[h]]>dp[j][j+i].u)||(f[j+i-1][b[h]]-f[j-1][b[h]]+num[b[h]]==dp[j][j+i].u&&b[h]<dp[j][j+i].v)) {                dp[j][j+i].u=f[j+i-1][b[h]]-f[j-1][b[h]]+num[b[h]];dp[j][j+i].v=b[h];            }        }    /*    for (i=1;i<=tot;i++) {        for (j=1;j<=tot;j++)        printf("%d %d %d %d\n", i, j, dp[i][j].u, dp[i][j].v);        printf("\n");    }    */}int getans(int l,int r) {    int i,x=0,y=0;    if (d[l]==d[r]) {        for (i=l;i<=r;i++) num[b[i]]=0;        for (i=l;i<=r;i++) num[b[i]]++;        for (i=l;i<=r;i++)        if ((num[b[i]]>x)||(num[b[i]]==x&&b[i]<y)) {            x=num[b[i]];y=b[i];        }    } else {        if (d[l]+1<=d[r]-1) {            x=dp[d[l]+1][d[r]-1].u;y=dp[d[l]+1][d[r]-1].v;        }        for (i=l;i<=d[l]*clo;i++) num[b[i]]=0;        for (i=(d[r]-1)*clo+1;i<=r;i++) num[b[i]]=0;        for (i=l;i<=d[l]*clo;i++) num[b[i]]++;        for (i=(d[r]-1)*clo+1;i<=r;i++) num[b[i]]++;        for (i=l;i<=d[l]*clo;i++)        if ((f[d[r]-1][b[i]]-f[d[l]][b[i]]+num[b[i]]>x)||(f[d[r]-1][b[i]]-f[d[l]][b[i]]+num[b[i]]==x&&b[i]<y)) {            x=f[d[r]-1][b[i]]-f[d[l]][b[i]]+num[b[i]];y=b[i];        }        for (i=(d[r]-1)*clo+1;i<=r;i++)        if ((f[d[r]-1][b[i]]-f[d[l]][b[i]]+num[b[i]]>x)||(f[d[r]-1][b[i]]-f[d[l]][b[i]]+num[b[i]]==x&&b[i]<y)) {            x=f[d[r]-1][b[i]]-f[d[l]][b[i]]+num[b[i]];y=b[i];        }    }    return c[y];}void query() {    int l,r,ans=0;    while (m--) {        scanf("%d%d", &l, &r);        l=(l+ans-1)%n+1;r=(r+ans-1)%n+1;        if (l>r) swap(l,r);        ans=getans(l,r);        printf("%d\n", ans);    }}int main(){    init();    deal();    query();    return 0;}/*6 31 2 3 2 1 21 53 61 57 778 876 876 765 3 2 31 33 41 75 71 25 63 720 109 8 6 9 1 7 6 5 7 8 6 5 8 6 4 6 3 2 1 61 1816 196 94 88 66 319 1118 1211 175 15*/


0 0
原创粉丝点击