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;
    }
  • 相关阅读:
    Windows环境下使用cygwin ndk_r9c编译FFmpeg
    android 开发环境搭建
    POJ 2559 单调栈入门,三种代码实现
    poj 2100 尺取法(尺度法)
    尺取算法 入门+模板+例题
    POJ 3579 Median 二分+思维
    POJ 3685 Matrix 二分套二分
    CodeForces 371C Hamburgers 二分
    HDU 4355 Party All the Time 三分算法
    HDU 3613 Best Reward Manacher算法
  • 原文地址:https://www.cnblogs.com/Gloid/p/9387949.html
Copyright © 2011-2022 走看看