• 作诗


    题目描述

    神犇SJY虐完HEOI之后给傻×LYD出了一题:

    SHY是T国的公主,平时的一大爱好是作诗。

    由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一些汉字构成诗。因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次。而且SHY认为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!)。于是SHY请LYD安排选法。

    LYD这种傻×当然不会了,于是向你请教……

    问题简述:N个数,M组询问,每次问[l,r]中有多少个数出现正偶数次。

    输入格式

    输入第一行三个整数n、c以及m。表示文章字数、汉字的种类数、要选择M次。

    第二行有n个整数,每个数Ai在[1, c]间,代表一个编码为Ai的汉字。

    接下来m行每行两个整数l和r,设上一个询问的答案为ans(第一个询问时ans=0),令L=(l+ans)mod n+1, R=(r+ans)mod n+1,若L>R,交换L和R,则本次询问为[L,R]。

    输出格式

    输出共m行,每行一个整数,第i个数表示SHY第i次能选出的汉字的最多种类数。

    预处理+分块

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    const int maxn=1e5+5;
    int n,m,c,T,siz;
    int a[maxn],cnt[maxn],belong[maxn],sum[320][maxn],ans[320][320];
    int main()
    {
        rd(n),rd(c),rd(m);
        siz=sqrt(n);
        T=siz;
        if(T*T<n)++T;
        inc(i,1,n)
        {
            rd(a[i]);
            belong[i]=(i-1)/siz+1;
            ++sum[belong[i]][a[i]];
        }
        inc(i,1,c)
        inc(j,1,T)
        sum[j][i]+=sum[j-1][i];
        
        inc(i,2,T-1)
        {
            int now=0;
            inc(j,i,T-1)
            {
                for(int k=(j-1)*siz+1;k<=j*siz;++k)
                {
                    ++cnt[a[k]];
                    if(!(cnt[a[k]]&1))++now;
                    else if(cnt[a[k]]>2)--now;
                }
                ans[i][j]=now;
            }
            inc(j,(i-1)*siz+1,(T-1)*siz)cnt[a[j]]=0;
        }
        
        int kk=0,l,r,L,R;
        inc(i,1,m)
        {
            rd(l),rd(r);
            l=(l+kk)%n+1;
            r=(r+kk)%n+1;
            if(l>r)swap(l,r);
            
            kk=0;
            if(belong[r]<=belong[l]+1)
            {
                for(int j=l;j<=r;++j)
                {
                    ++cnt[a[j]];
                    if(!(cnt[a[j]]&1))++kk;
                    else if(cnt[a[j]]>2)--kk;
                }
                for(int j=l;j<=r;++j)
                cnt[a[j]]=0;
            }
            else 
            {
                L=belong[l];R=belong[r]-1;
                kk=ans[belong[l]+1][R];
                for(int j=l;j<=belong[l]*siz;++j)
                {
                    ++cnt[a[j]];
                    if(!((cnt[a[j]]+sum[R][a[j]]-sum[L][a[j]])&1))++kk;
                    else if((cnt[a[j]]+sum[R][a[j]]-sum[L][a[j]])>2)--kk;
                }
                
                for(int j=R*siz+1;j<=r;++j)
                {
                    ++cnt[a[j]];
                    if(!(((cnt[a[j]]+sum[R][a[j]]-sum[L][a[j]]))&1))++kk;
                    else if((cnt[a[j]]+sum[R][a[j]]-sum[L][a[j]])>2)--kk;
                }
                inc(j,l,belong[l]*siz)cnt[a[j]]=0;
                inc(j,R*siz+1,r)cnt[a[j]]=0;
            }
            printf("%d
    ",kk);
        }
        re 0;
    } 
    View Code
  • 相关阅读:
    打包压缩文件命令
    用户与组管理命令
    cut 命令 通过列来提取文本字符
    linux文件拼接命令 paste
    shell 指定范围产生随机数
    shell 脚本随机抽取班级学生
    shell 输出九九乘法表
    shell 判断语句
    linux 排序命令sort
    linux之PATH环境变量
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11724845.html
Copyright © 2020-2023  润新知