zoukankan      html  css  js  c++  java
  • BZOJ2821 作诗(分块)

    和区间众数几乎一模一样的套路。

    // luogu-judger-enable-o2
    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 100010
    #define BLOCK 350
    int n,m,c,a[N],lastans=0;
    int block,tot,L[N],R[N],pos[N];
    int cnt[N],f[BLOCK][BLOCK],sum[BLOCK][N];
    int main()
    {
        freopen("bzoj2821.in","r",stdin);
        freopen("bzoj2821.out","w",stdout);
        n=read(),c=read(),m=read();
        for (int i=1;i<=n;i++) a[i]=read();
        block=sqrt(n);tot=n/block+(n%block>0);
        for (int i=1;i<=n/block;i++)
        L[i]=(i-1)*block+1,R[i]=(i-1)*block+block;
        if (n/block<tot) L[tot]=n/block*block+1,R[tot]=n;
        for (int i=1;i<=tot;i++)
        {
            memset(cnt,0,sizeof(cnt));
            for (int j=i;j<=tot;j++)
            {
                f[i][j]=f[i][j-1];
                for (int k=L[j];k<=R[j];k++)
                {
                    cnt[a[k]]++;
                    if (!(cnt[a[k]]&1)) f[i][j]++;
                    else if (cnt[a[k]]>1) f[i][j]--;
                }
            }
            memcpy(sum[i],sum[i-1],sizeof(sum[i]));
            for (int j=L[i];j<=R[i];j++)
            pos[j]=i,sum[i][a[j]]++;
        }
        memset(cnt,0,sizeof(cnt));
        while (m--)
        {
            int x=read(),y=read();
            x=(x+lastans)%n+1,y=(y+lastans)%n+1;
            if (x>y) swap(x,y);
            int num=0;
            if (pos[x]==pos[y])
            {
                for (int i=x;i<=y;i++)
                {
                    cnt[a[i]]++;
                    if (!(cnt[a[i]]&1)) num++;
                    else if (cnt[a[i]]>1) num--;
                }
                for (int i=x;i<=y;i++) cnt[a[i]]--;
            }
            else
            {
                num=f[pos[x]+1][pos[y]-1];
                for (int i=x;i<=R[pos[x]];i++)
                {
                    cnt[a[i]]++;
                    if (!(cnt[a[i]]+sum[pos[y]-1][a[i]]-sum[pos[x]][a[i]]&1)) num++;
                    else if (cnt[a[i]]+sum[pos[y]-1][a[i]]-sum[pos[x]][a[i]]>1) num--;
                }
                for (int i=L[pos[y]];i<=y;i++)
                {
                    cnt[a[i]]++;
                    if (!(cnt[a[i]]+sum[pos[y]-1][a[i]]-sum[pos[x]][a[i]]&1)) num++;
                    else if (cnt[a[i]]+sum[pos[y]-1][a[i]]-sum[pos[x]][a[i]]>1) num--;
                }
                for (int i=x;i<=R[pos[x]];i++) cnt[a[i]]--;
                for (int i=L[pos[y]];i<=y;i++) cnt[a[i]]--;
            }
            lastans=num;
            printf("%d
    ",num);
        }
        return 0;
    }
  • 相关阅读:
    树的直径、重心、中心
    DP优化--四边形不等式
    P5569 【SDOI2008】 石子合并(黑科技)
    P3147 262144游戏
    P3205 【HNOI2010】合唱队
    Windows Server 2012 虚拟化实战:网络(一)
    Windows Server 2012 虚拟化实战:存储(二)
    Android使用最小宽度限定符时最小宽度的计算
    Eclipse调试Android App若选择“Use same device for future launches”就再也无法选择其他设备的问题
    Python的模块引用和查找路径
  • 原文地址:https://www.cnblogs.com/Gloid/p/9387949.html
Copyright © 2011-2022 走看看