bzoj 2795: [Poi2012]A Horrible Poem hash
来源:互联网 发布:godaddy免费域名 编辑:程序博客网 时间:2024/06/05 19:22
题意
给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节。
如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到。
n<=500000,q<=2000000
分析
一开始啥都想不到,然后才发现原来正解就是暴力。
对于每一个区间,设其长度为len,其循环长度一定为n的约数。那么我们可以枚举循环节长度,是否是循环节的话就可以用hashO(1)判断了。
问题是这样比较慢,考虑优化。
其循环节的周期必然也是字符串中每个字符出现次数的约数,那么只要把len与所有字符出现的次数取个gcd,然后再O(sqrtn)枚举约数就好了。
代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int N=500005;const int MOD1=233333333;const int MOD2=1000000007;int n,q,s[N][27],mi1[N],mi2[N],hash1[N],hash2[N];char ch[N];int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int gcd(int x,int y){ if (!y) return x; else return gcd(y,x%y);}bool check(int x,int y,int len){ int u1=(hash1[x+len-1]-(LL)hash1[x-1]*mi1[len]%MOD1+MOD1)%MOD1; int v1=(hash2[x+len-1]-(LL)hash2[x-1]*mi2[len]%MOD2+MOD2)%MOD2; int u2=(hash1[y+len-1]-(LL)hash1[y-1]*mi1[len]%MOD1+MOD1)%MOD1; int v2=(hash2[y+len-1]-(LL)hash2[y-1]*mi2[len]%MOD2+MOD2)%MOD2; if (u1==u2&&v1==v2) return 1; else return 0;}int main(){ n=read(); scanf("%s",ch+1); mi1[0]=mi2[0]=1; for (int i=1;i<=n;i++) { for (int j=0;j<26;j++) s[i][j]=s[i-1][j]; s[i][ch[i]-'a']++; hash1[i]=((LL)hash1[i-1]*27%MOD1+ch[i]-'a'+1)%MOD1; hash2[i]=((LL)hash2[i-1]*27%MOD2+ch[i]-'a'+1)%MOD2; mi1[i]=(LL)mi1[i-1]*27%MOD1; mi2[i]=(LL)mi2[i-1]*27%MOD2; } q=read(); for (int i=1;i<=q;i++) { int l=read(),r=read(); int len=r-l+1,k=len; for (int j=0;j<26;j++) if (s[r][j]-s[l-1][j]) k=gcd(k,s[r][j]-s[l-1][j]); int ans=1; for (int j=1;j*j<=k;j++) if (k%j==0) { if (check(l,l+len/j,len-len/j)) ans=max(ans,j); if (check(l,l+len/(k/j),len-len/(k/j))) ans=max(ans,k/j); } printf("%d\n",(r-l+1)/ans); } return 0;}
阅读全文
0 0
- BZOJ 2795 Poi2012 A Horrible Poem Hash
- bzoj 2795 [Poi2012]A Horrible Poem hash
- bzoj 2795: [Poi2012]A Horrible Poem hash
- 2795: [Poi2012]A Horrible Poem hash
- [BZOJ 2795]POI2012 A Horrible Poem
- BZOJ 2795:[Poi2012]A Horrible Poem
- 2795: [Poi2012]A Horrible Poem
- 字符串hash,bzoj2795[Poi2012]A Horrible Poem
- 【bzoj2795】[Poi2012]A Horrible Poem hash
- [BZOJ2795] [Poi2012] [字符串hash] A Horrible Poem
- bzoj2795[Poi2012]A Horrible Poem 暴力hash
- bzoj-2795 A Horrible Poem
- 【BZOJ2795】[Poi2012]A Horrible Poem【Hash】【GCD】【暴力】
- 【POI2012】【BZOJ2795】A Horrible Poem
- BZOJ2795: [Poi2012]A Horrible Poem
- BZOJ2795 [Poi2012]A Horrible Poem
- bzoj2795: [Poi2012]A Horrible Poem
- BZOJ2795/POI2012 A horrible poem
- bzoj2442
- 数据预处理:AMiner to JSON
- 有什么办法能控制微信群红包的尾数大小单双
- MATLAB笔记 sparse稀疏矩阵函数
- 深入了解jQuery之整体架构
- bzoj 2795: [Poi2012]A Horrible Poem hash
- linux下bin安装包制作教程
- Activity四种启动模式
- xtu 1268 Strange Optimization 湘潭邀请赛I
- python 多线程
- java中验证18位身份证的正则表达式
- input搜索筛选\过滤列表
- (转)jQuery中的extend()方法
- const与static关键字