bzoj 2821: 作诗(Poetize)
2015-02-10 00:57
295 查看
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次能选出的汉字的最多种类数。Sample Input
5 3 51 2 2 3 1
0 4
1 2
2 2
2 3
3 5
Sample Output
20
0
0
1
HINT
对于100%的数据,1<=n,c,m<=10^5Source
By lydrainbowcat写这题的时候大滚粗。各种错误不断。对拍用的暴力程序都可以写错
对于这题,因为强制在线,所以可以用分块来解决
用fx[i][j]表示第i块到第j块的答案,f[i][x]表示第块颜色x的种类
然后对于询问。我们只需要统计出包含其的区间答案。然后把不在询问的区间的元素分类讨论下ans加加减减即可
#include<cmath> #include<cstdio> #include<string> #include<cstring> #include<algorithm> using namespace std; int a[100001],sa[1001],sax[100001],sx[100001]; int f[320][100001]; int fx[320][320]; int belong[100001]; bool v[1001]; int tx[1001]; int ft[100001]; int main() { // freopen("make.in","r",stdin); // freopen("make.out","w",stdout); int n,c,m; scanf("%d%d%d",&n,&c,&m); int i,j,k; for(i=1;i<=n;i++) scanf("%d",&a[i]); int nt=sqrt(n); for(i=1;i<=n;i++) { belong[i]=(i-1)/nt+1; f[belong[i]][a[i]]++; } for(i=1;i<=(n-1)/nt+1;i++) for(j=1;j<=c;j++) f[i][j]+=f[i-1][j]; for(i=1;i<=(n-1)/nt+1;i++) { memset(sax,0,sizeof(sax)); int ans=0; for(j=i;j<=(n-1)/nt+1;j++) { int ed=min(j*nt,n); for(k=(j-1)*nt+1;k<=ed;k++) { sax[a[k]]++; if(sax[a[k]]%2==0) ans++; else if(sax[a[k]]!=1) ans--; } fx[i][j]=ans; } } int s,t; int la=0; for(i=1;i<=m;i++) { scanf("%d%d",&s,&t); s=(s+la)%n+1; t=(t+la)%n+1; if(s>t) { int tt=s; s=t; t=tt; } int l=belong[s],r=belong[t]; int ans=fx[l][r]; memset(sa,0,sizeof(sa)); memset(v,false,sizeof(v)); int ed=min(r*nt,n); int p=0; for(j=(l-1)*nt+1;j<=s-1;j++) { p++; tx[p]=a[j]; v[p]=true; } for(j=t+1;j<=ed;j++) { p++; tx[p]=a[j]; v[p]=true; } sort(tx+1,tx+1+p); int pt=0; for(j=1;j<=p;j++) { if(tx[j]!=tx[j-1]) { pt++; ft[tx[j]]=pt; } sa[pt]++; } for(j=(l-1)*nt+1;j<=s-1;j++) { if(!v[ft[a[j]]]) continue; int xx=f[r][a[j]]-f[l-1][a[j]]; if(xx%2==0&&sa[ft[a[j]]]%2==1||sa[ft[a[j]]]==xx&&xx!=0&&xx%2==0) ans--; else if(xx%2==1&&sa[ft[a[j]]]%2==1&&xx!=sa[ft[a[j]]]) ans++; v[ft[a[j]]]=false; } for(j=t+1;j<=ed;j++) { if(!v[ft[a[j]]]) continue; int xx=f[r][a[j]]-f[l-1][a[j]]; if(xx%2==0&&sa[ft[a[j]]]%2==1||sa[ft[a[j]]]==xx&&xx!=0&&xx%2==0) ans--; else if(xx%2==1&&sa[ft[a[j]]]%2==1&&xx!=sa[ft[a[j]]]) ans++; v[ft[a[j]]]=false; } printf("%d\n",ans); la=ans; } return 0; }
相关文章推荐
- BZOJ 2821 作诗(Poetize)(分块)
- BZOJ 2821: 作诗(Poetize) | 分块
- 【bzoj2821】作诗(Poetize) 分块
- 【分块】bzoj2821 作诗(Poetize)
- BZOJ2821: 作诗(Poetize)
- bzoj2821[作诗(Poetize)]
- BZOJ 2821 作诗(Poetize)
- BZOJ 2821: 作诗(Poetize)|分块
- 【bzoj2821】作诗(Poetize)
- bzoj 2821: 作诗(Poetize) (分块)
- 分块-bzoj2821: 作诗(Poetize)
- bzoj 2821: 作诗(Poetize)【分块】
- 【BZOJ2821】作诗(Poetize) 分块
- BZOJ 2821: 作诗(Poetize) [分块]
- BZOJ 2821 作诗(Poetize)
- BZOJ 2821: 作诗(Poetize)( 分块 )
- [BZOJ 2821] 作诗(Poetize) 【分块】
- 【bzoj2821】作诗(Poetize)
- bzoj 2821: 作诗(Poetize) 分块
- BZOJ2821 作诗(Poetize) 【分块】