【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

8
aaabcabc
3
1 3
3 8
4 8

Sample Output

1
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的更多相关文章

  1. 【bzoj2795】[Poi2012]A Horrible Poem Hash+分解质因数

    题目描述 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. 输入 第一行一个正整数n (n<= ...

  2. BZOJ 2795: [Poi2012]A Horrible Poem( hash )

    ...字符串hash. 假如长度x是一个循环节, 那么对于任意n(x | n)也是一个循环节. 设当前询问区间[l, r]长度为len = ∏piai, 最终答案ans = ∏piai' ,我们只需枚 ...

  3. bzoj 2795 [Poi2012]A Horrible Poem hash+数论

    2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 640  Solved: 322[Subm ...

  4. BZOJ2795&2890&3647[Poi2012]A Horrible Poem——hash

    题目描述 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. 输入 第一行一个正整数n (n<= ...

  5. [POI2012]OKR-A Horrible Poem hash

    题面:洛谷 题解: 首先我们需要知道一个性质,串s的最小循环节 = len - next[len].其中next[len]表示串s的一个最长长度使得s[1] ~ s[next[len]] == s[l ...

  6. bzoj 2795 [Poi2012]A Horrible Poem hash+线性筛

    题目大意 bzoj 2795 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节. 如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. n<=500 ...

  7. P3538 [POI2012]OKR-A Horrible Poem

    P3538 [POI2012]OKR-A Horrible Poem hash+线性筛 题解 <----这篇写的不错(其实是我懒得码字了qwq) UVA10298 Power Strings 的 ...

  8. [BZOJ2795][Poi2012]A Horrible Poem

    2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 261  Solved: 150[Subm ...

  9. 2795: [Poi2012]A Horrible Poem

    2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 484  Solved: 235[Subm ...

随机推荐

  1. 【CF733F】Drivers Dissatisfaction(最小瓶颈生成树,倍增)

    题意:给出一个图,每条边有权值和花费c,每次花费c能使的权值-1.给出一个预算,求减完权值后的一个最小生成树. 思路:感谢CC大神 有这样一个结论:最佳方案里必定存在一种,预算全部花费全部分配在一条边 ...

  2. 16深入理解C指针之---迷途指针

    一.若程序中存在迷途指针,轻则导致程序退出,重则使程序出现重大逻辑错误 1.定义:内存已释放,指针依旧指向原始内存,这种指针就是迷途指针 2.迷途指针和指针别名: 1).指针依旧指向已释放的内存,无法 ...

  3. CentOS找不到想要的镜像版本?

    CentOS找不到想要的镜像版本? 情景: 当学习Linux时,一般教程不是最新的,教程里的CentOS版本也就不是最新的,这个时候, 在看着教程练习的时候就需要安装指定的版本,避免因为版本不同造成困 ...

  4. Vue中的computed 解读

    computed相当于属性的一个实时计算,如果实时计算里关联了对象,那么当对象的某个值改变的时候,同事会出发实时计算.比如: <body id="content"> & ...

  5. Adoquery的 moveby和GotoBookmark,RecNo

    GotoBookmark 是必须存在的记录,再次返回原来那个记录的位置,但是原来的那个记录必须存在,所以不适合[删除订单后回到原来的位置],因为原来的订单已经不存在了,删除了, moveby(),从当 ...

  6. zoj 2760(网络流+floyed)

    How Many Shortest Path Time Limit: 10 Seconds      Memory Limit: 32768 KB Given a weighted directed ...

  7. vue 之循环添加不同class

    在vue中按条件为class动态添加直接使用:class="[{ active: isActive }, errorClass]"之类的表达式就可以 但是如果我们要为一个循环列表按 ...

  8. 基于python的性能测试工具–locust

    现在有很多的性能测试工具,比如说我们熟悉的loadrunner.jmeter.ab.webbench等等,这些工具如果对一个没用过的朋友来说,学习起来比较不容易,但是如果你能看懂python代码,会写 ...

  9. Javascript 评估用户输入密码的强度

    什么是一个安全的密码呢? 1.如果密码少于5位,那么就认为这是一个弱密码. 2.如果密码只由数字.小写字母.大写字母或其它特殊符号当中的一种组成,则认为这是一个弱密码. 3.如果密码由数字.小写字母. ...

  10. Unity3d Inspector面板实现set/get访问器

    简单说一下属性和字段的区别:字段就是成员变量,而属性确实提供给外部访问内部成员变量的接口.之所以会有属性的出现,就是为了避免外部对类的成员的直接访问,通俗的说就是OOP中的封装思想. using Un ...