作诗

 

题目描述

神犇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\n",kk);
    }
    re 0;
} 
View Code

 

posted @ 2019-10-23 10:35  凉如水  阅读(206)  评论(0编辑  收藏  举报