bzoj2821 作诗

原创 2016年10月11日 15:01:07

Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗。由于时间紧迫,SHY作完诗
之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一
些汉字构成诗。因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次。而且SHY认
为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!)。于是SHY请LYD安排选
法。LYD这种傻×当然不会了,于是向你请教……问题简述:N个数,M组询问,每次问[l,r]中有多少个数出现正偶 数次。

Input 输入第一行三个整数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]。

Output

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

分块。
首先预处理出任意连续的几段中出现偶数次的数字个数,以及每个数在序列中出现的位置下标。
对于在非整块中出现的数暴力统计,结合在整块中出现的次数讨论得出答案。

#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
int a[100010],L[10010],R[10010],sta[100010],
tot[5010][5010],cnt[100010],last[100010],m,n,T;
vector<int> plc[100010];
vector<int>::iterator i1,i2;
int num(int x,int l,int r)
{
    i1=lower_bound(plc[x].begin(),plc[x].end(),l);
    i2=upper_bound(plc[x].begin(),plc[x].end(),r);
    return i2-i1;
}
int rd()
{
    int x=0;
    char c=getchar();
    while (c<'0'||c>'9') c=getchar();
    while (c>='0'&&c<='9')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    return x;
}
int main()
{
    int c,i,j,k,p,q,x,y,z,ans,l,r,ll,rr,K,top,size;
    scanf("%d%d%d",&n,&c,&m);
    for (i=1;i<=n;i++)
    {
        a[i]=rd();
        plc[a[i]].push_back(i);
    }
    size=sqrt((double)n/log(n)*log(2));
    if (n%size) T=n/size+1;
    else T=n/size;
    for (i=1;i<=T;i++)
    {
        L[i]=R[i-1]+1;
        R[i]=i==T?n:L[i]+size-1;
    }
    for (i=1;i<=T;i++)
    {
        for (j=i;j<=T;j++)
        {
            tot[i][j]=tot[i][j-1];
            for (k=L[j];k<=R[j];k++)
            {
                if (last[a[k]]<i)
                {
                    last[a[k]]=i;
                    cnt[a[k]]=1;
                }
                else cnt[a[k]]++;
                if (cnt[a[k]]&1^1) tot[i][j]++;
                else
                {
                    if (cnt[a[k]]>1) tot[i][j]--;
                }
            }
        }
    }
    ans=0;
    memset(last,0,sizeof(last));
    for (K=1;K<=m;K++)
    {
        l=rd();
        r=rd();
        l=(l+ans)%n+1;
        r=(r+ans)%n+1;
        if (l>r) swap(l,r);
        ll=1;
        while (L[ll]<l&&ll<=T) ll++;
        rr=T;
        while (R[rr]>r&&rr) rr--;
        if (ll>rr)
        {
            ans=0;
            for (i=l;i<=r;i++)
              if (last[a[i]]<K)
              {
                last[a[i]]=K;
                if (num(a[i],l,r)&1^1) ans++;
              }
            printf("%d\n",ans);
            continue;
        }
        ans=tot[ll][rr];
        top=0;
        for (i=l;i<L[ll];i++)
          if (last[a[i]]<K)
          {
            last[a[i]]=K;
            sta[++top]=a[i];
          }
        for (i=R[rr]+1;i<=r;i++)
          if (last[a[i]]<K)
          {
            last[a[i]]=K;
            sta[++top]=a[i];
          }
        for (i=1;i<=top;i++)
        {
            x=num(sta[i],L[ll],R[rr]);
            if (!x||(x&1))
            {
                if (num(sta[i],l,r)&1^1) ans++;
            }
            else
            {
                if (num(sta[i],l,r)&1) ans--;
            }
        }
        printf("%d\n",ans);
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载,欢迎添加友链。

相关文章推荐

bzoj2821[作诗(Poetize)]

BZOJ2821 作诗

BZOJ2821: 作诗(Poetize)(分块)

传送门 题意 给你一个区间,每次查询(l,r),问(l,r)中数字出现偶数次的种类数。 题解 分块大法好。。。 分析: 1.查询(l,r)中的数字出现偶数次的种类数,可以等价于完整块中数字种类数及...

BZOJ 2821 作诗 [区间众数]

类似的有BZOJ 蒲公英 区间众数这种线段树解决不了的题,用分块暴力准没有错。#include using namespace std; const int N = 100005; int l,r,...

BZOJ 2821 作诗(Poetize) 分块

题目大意:给定一个序列 多次求区间中多少个数出现次数为偶数次 强制在线 很神的一道分块的题……记得刚进BZ坑的时候看到这道题50秒特别惊奇0.0 然后我就作死去交了个死循环0.0 看了很多题解 都...
  • PoPoQQQ
  • PoPoQQQ
  • 2014年10月22日 10:14
  • 1920

【bzoj 2821】 作诗 题意&题解&代码(C++)

分块
  • DERITt
  • DERITt
  • 2016年03月17日 21:14
  • 309

bzoj2821: 作诗(Poetize)

传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2821 思路:分块大法好。。。 分成sqrt(n)块,先预处理出连续的块的答案,f[i...

bzoj2821 作诗(Poetize)

神奇的分块题,求大家帮助

BZOJ 2821 作诗(Poetize)

(在线)分块+二分

【BZOJ】【P2821】【作诗(Poetize)】【题解】【分块】

/* ID:zky OJ:BZOJ Index:2821 Language:C++ */ #include #include #include #include #include #inclu...

bzoj 2821: 作诗(Poetize)

Description 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗。 由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读...
  • lqybzx
  • lqybzx
  • 2015年02月10日 00:57
  • 520
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:bzoj2821 作诗
举报原因:
原因补充:

(最多只允许输入30个字)