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);
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载,欢迎添加友链。

BZOJ 2821 作诗(Poetize) 分块

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

bzoj2821: 作诗(Poetize)

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

BZOJ2821(作诗)

2821: 作诗(Poetize) Time Limit: 50 Sec  Memory Limit: 128 MB Submit: 1004  Solved: 321 [Submit][Sta...
  • cymxyym
  • cymxyym
  • 2014年06月12日 14:38
  • 401

[bzoj2821]作诗

题目大意询问区间出现次数为正偶数的数的个数分块大法好经典分块方法。 预处理ans[i,j]表示第i块到第j块的答案,sum[i,j]表示前j块中元素i出现的次数。 然后搞一波就行了。 bzoj上...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2016年03月07日 14:03
  • 442

【bzoj2821】作诗(Poetize)

*题目描述: 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗。由于时间紧迫,SHY作完诗 之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次...
  • qq_33442848
  • qq_33442848
  • 2016年05月23日 11:33
  • 124

bzoj2821 作诗(Poetize)

神奇的分块题,求大家帮助
  • AaronGZK
  • AaronGZK
  • 2016年03月03日 23:01
  • 1162

BZOJ2821: 作诗(Poetize)

分块,因为没有修改的操作,在线询问,所以可以预处理出s[i][j]表示1到i块j出现的次数,f[i][j]表示i到j块有多少数出现次数为偶数,询问时两端的块暴力做一下就行了 题目卡空间(有毒),把块...
  • L_0_Forever_LF
  • L_0_Forever_LF
  • 2016年10月28日 09:52
  • 554

【bzoj2821】【作诗】【分块】

Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗。由于时间紧迫,SHY作完诗 之后还要虐OI,于是SHY找来一篇长度为N的文章,...
  • sunshinezff
  • sunshinezff
  • 2016年06月17日 19:45
  • 173

BZOJ2821: 作诗(Poetize)(分块)

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

bzoj2821[作诗(Poetize)]

BZOJ2821 作诗
  • qq_37321281
  • qq_37321281
  • 2017年07月19日 21:19
  • 81
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:bzoj2821 作诗
举报原因:
原因补充:

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