【BZOJ2795】[Poi2012]A Horrible Poem hash
【BZOJ2795】[Poi2012]A Horrible Poem
Description
给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节。
如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到。
Input
第一行一个正整数n (n<=500,000),表示S的长度。
第二行n个小写英文字母,表示字符串S。
第三行一个正整数q (q<=2,000,000),表示询问个数。
下面q行每行两个正整数a,b (1<=a<=b<=n),表示询问字符串S[a..b]的最短循环节长度。
Output
依次输出q行正整数,第i行的正整数对应第i个询问的答案。
Sample Input
aaabcabc
3
1 3
3 8
4 8
Sample Output
3
5
题解:回忆用KMP求一个单词最短循环节的方法,如果next[n]>=n/2,则最短循环节为n-next[n]。
那么我们就得出了O(1)判断一个长度x是否是给定串的循环节的方法,直接用hash判断s[l...r-x]和s[l+x...r]是否相等即可,那么我们思考这个最短长度是什么。
首先如果x是该串的循环节,则2x,3x也一定是该串的循环节,并且我们已知原串长度len一定是它本身的循环节,那么x一定是len的约数。我们可以将len分解质因数,x的每个质因子的次数一定<=len中每个质因子的次数,从大到小枚举这个次数即可。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const ll m1=998244353;
const ll m2=100000007;
const int maxn=500010;
int n,q,num,ans;
char str[maxn];
int pri[maxn],lp[maxn];
ll b1[maxn],b2[maxn],h1[maxn],h2[maxn];
bool np[maxn];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
bool check(int a,int b,int c,int d)
{
return (h1[b]-h1[a-1]*b1[b-a+1]%m1+m1)%m1==(h1[d]-h1[c-1]*b1[d-c+1]%m1+m1)%m1&&(h2[b]-h2[a-1]*b2[b-a+1]%m2+m2)%m2==(h2[d]-h2[c-1]*b2[d-c+1]%m2+m2)%m2;
}
int main()
{
scanf("%d%s%d",&n,str+1,&q);
int i,j,a,b,c;
for(i=2;i<=n;i++)
{
if(!lp[i]) pri[++num]=lp[i]=i;
for(j=1;j<=num&&i*pri[j]<=n;j++)
{
lp[i*pri[j]]=pri[j];
if(i%pri[j]==0) break;
}
}
for(b1[0]=b2[0]=1,i=1;i<=n;i++)
{
h1[i]=(h1[i-1]*233+str[i])%m1,h2[i]=(h2[i-1]*233+str[i])%m2;
b1[i]=b1[i-1]*233%m1,b2[i]=b2[i-1]*233%m2;
}
for(i=1;i<=q;i++)
{
a=rd(),b=rd(),c=ans=b-a+1;
while(c!=1)
{
if(check(a,b-ans/lp[c],a+ans/lp[c],b)) ans/=lp[c];
c/=lp[c];
}
printf("%d\n",ans);
}
return 0;
}//8 aaabcabc 3 1 3 3 8 4 8
【BZOJ2795】[Poi2012]A Horrible Poem hash的更多相关文章
- 【bzoj2795】[Poi2012]A Horrible Poem Hash+分解质因数
题目描述 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. 输入 第一行一个正整数n (n<= ...
- BZOJ 2795: [Poi2012]A Horrible Poem( hash )
...字符串hash. 假如长度x是一个循环节, 那么对于任意n(x | n)也是一个循环节. 设当前询问区间[l, r]长度为len = ∏piai, 最终答案ans = ∏piai' ,我们只需枚 ...
- bzoj 2795 [Poi2012]A Horrible Poem hash+数论
2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 640 Solved: 322[Subm ...
- BZOJ2795&2890&3647[Poi2012]A Horrible Poem——hash
题目描述 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. 输入 第一行一个正整数n (n<= ...
- [POI2012]OKR-A Horrible Poem hash
题面:洛谷 题解: 首先我们需要知道一个性质,串s的最小循环节 = len - next[len].其中next[len]表示串s的一个最长长度使得s[1] ~ s[next[len]] == s[l ...
- bzoj 2795 [Poi2012]A Horrible Poem hash+线性筛
题目大意 bzoj 2795 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节. 如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. n<=500 ...
- P3538 [POI2012]OKR-A Horrible Poem
P3538 [POI2012]OKR-A Horrible Poem hash+线性筛 题解 <----这篇写的不错(其实是我懒得码字了qwq) UVA10298 Power Strings 的 ...
- [BZOJ2795][Poi2012]A Horrible Poem
2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 261 Solved: 150[Subm ...
- 2795: [Poi2012]A Horrible Poem
2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 484 Solved: 235[Subm ...
随机推荐
- spoj 7001 Visible Lattice Points莫比乌斯反演
Visible Lattice Points Time Limit:7000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Su ...
- hdu 1754 线段树(点修改)
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- yii 数据库添加,修改,删除相关操作总结
yii中关于数据信息的添加数据,修改数据,删除数据的相关操作,刚刚学习没几天,仅记录了一些,以后慢慢再充实,有需要的朋友可以看看. 添加数据的方法 (1)save 方法(对象形式操作) $user=n ...
- LightOJ 1140: How Many Zeroes? (数位DP)
当前数位DP还不理解的点: 1:出口用i==0的方式 2:如何省略状态d(就是枚举下一个数的那个状态.当然枚举还是要的,怎么把空间省了) 总结: 1:此类DP,考虑转移的时候,应当同时考虑查询时候的情 ...
- OpenOPC
客户端连接OpenOPC Gateway import OpenOPC gateway='192.168.1.90' opchost='testbox' opcserv='KEPware.KEPSer ...
- AC日记——爱改名的小融 codevs 2967
2967 爱改名的小融 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 白银 Silver 题解 题目描述 Description Wikioi上有个人叫小融,他喜欢 ...
- js-页面进入时同时实现-图片预加载
下面的是我认为最简单的预加载图片里!在页面进入时就开始加载 var imgARR = ['images/xmImg1.png','images/xmImg2.png','images/xmImg3.p ...
- Symmetric Tree(DFS,二叉树的构建以及测试代码)
基础有待加强啊,由该题引发出来一些问题,现在来总结下. 首先是二叉树的结构: struct TreeNode { EleType val; TreeNode *left; TreeNode *righ ...
- 从源码解析 Spring JDBC 异常抽象
初入学习 JDBC 操作数据库,想必大家都写过下面的代码: 数据库为:H2 如果需要处理特定 SQL 异常,比如 SQL 语句错误,这个时候我们应该怎么办? 查看 SQLException 源码,我们 ...
- Android自定义控件之自定义组合控件(三)
前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...