题面:洛谷

题解:

  首先我们需要知道一个性质,串s的最小循环节 = len - next[len].其中next[len]表示串s的一个最长长度使得s[1] ~ s[next[len]] == s[len - next[len] + 1] ~ s[len](详细定义参见KMP)

  至于为什么是成立的可以画图推一下,这个应该是比较常见的性质。

  

  可能画的有点丑。。。

  图中每个绿色方块所代表的串都是相同的,因为第一个绿块显然与下面那块相同,而根据next的定义,它也与第二行第二个绿块相同……以此类推,可以一直递推下去,直到推完整个数组。

  

  对于一个长度为len的串s而言,设它的最小循环节长度为l.

  若$len = p_{1}^{k_{1}} \cdot p_{2}^{k_{2}} \cdot p_{3}^{k_{3}}...p_{t}^{k_{t}}$

  则$len = p_{1}^{a_{1}} \cdot p_{2}^{a_{2}} \cdot p_{3}^{a_{3}}...p_{t}^{a_{t}}$其中$a_{i} \le k_{i}$.

  首先一个串的最大循环节长度肯定= len;

  而这个循环节之所以可以变小,是因为这个最大循环节是由很多个最短循环节组成。我们假设最短循环节为X,这这个串可以表示为XXXXXXX(若干个X)

  假设X有b个。那么我们可以每次对b缩减一个b的因子,最后使得b变为1,即使b不断除一个数。

  例如一个串s一开始可以被表示为XXXXXXXX(8个X),即b = 8

  这个时候我们枚举到一个2,于是我们判断原串是否可以被XXXX + XXXX凑出,如果可以,那么b /= 2.

  然后我们判断原串是否可以被XX + XX + XX + XX凑出,如果可以,那么b /= 2.

  依次类推,直到已经没有更小的循环节可以凑出原串位置。

  其中2是b的某个质因子。

  因为b的最大值为len(即循环节为1),所以我们一开始先从len开始,不断枚举len的质因子,看能否消去这个因子,最后剩下的数就是答案。

  判断一个长度是否可以成立,可以用hash判断图中红色部分是否相等

  

  其中绿块长度为x。

  原理就是一开始解释过的KMP求最小循环节。

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 501000
#define p1 1000000007
#define p2 998244353
#define base 26
#define LL long long int n, m, tot, top;
int hash1[AC], hash2[AC], pw1[AC], pw2[AC];
int pri[AC], last[AC], q[AC];
char s[AC];
bool z[AC]; inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} void get()//欧拉筛
{
for(R i = ; i <= n; i ++)
{
if(!z[i]) pri[++ tot] = i, last[i] = i;
for(R j = ; j <= tot; j ++)
{
int now = pri[j];
if(now * i > n) break;
z[now * i] = true, last[now * i] = now;
if(!(i % now)) break;
}
}
} void pre()
{
n = read();
scanf("%s", s + );
} void build()//求前缀hash值
{
pw1[] = pw2[] = ;
for(R i = ; i <= n; i ++)
{
hash1[i] = (1ll * hash1[i - ] * base + s[i] - 'a' + ) % p1;
hash2[i] = (1ll * hash2[i - ] * base + s[i] - 'a' + ) % p2;
pw1[i] = 1ll * pw1[i - ] * base % p1;//存下base的i次方
pw2[i] = 1ll * pw2[i - ] * base % p2;
}
} LL cal(int l, int r, bool w){
if(!w) return ((1ll * hash1[r] - 1ll * hash1[l - ] * pw1[r - l + ] % p1) + p1) % p1;
else return ((hash2[r] - 1ll * hash2[l - ] * pw2[r - l + ] % p2) + p2) % p2;
} bool check(int l, int r, int x){//测试区间[l, r]的循环结是否可能为x
return (cal(l + x, r, ) == cal(l, r - x, )) && (cal(l + x, r, ) == cal(l, r - x, ));
} void work()
{
m = read();
for(R i = ; i <= m; i ++)
{
int l = read(), r = read(), x = r - l + ;
top = ;
while(x != ) q[++ top] = last[x], x /= last[x];
x = r - l + ;
for(R i = ; i <= top; i ++)
if(check(l, r, x / q[i])) x /= q[i];
printf("%d\n", x);
}
} int main()
{
// freopen("in.in", "r", stdin);
pre();
get();//处理last数组
build();//构建hash数组
work();
// fclose(stdin);
return ;
}

  

[POI2012]OKR-A Horrible Poem hash的更多相关文章

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

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

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

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

  3. 【BZOJ2795】[Poi2012]A Horrible Poem hash

    [BZOJ2795][Poi2012]A Horrible Poem Description 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串 ...

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

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

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

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

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

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

  7. 【bzoj2795】【Poi2012】A Horrible Poem

    题解: 询问区间的整循环节 设区间长度为$n$ 如果有循环节长为$x$和$y$,那由斐蜀定理得$gcd(x,y)$也一定为一个循环节: 假设最小的循环节长为$mn$,那么对于任何循环节长$x$,一定$ ...

  8. P3538 [POI2012]OKR-A Horrible Poem

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

  9. 洛谷P3538 [POI2012]OKR-A Horrible Poem [字符串hash]

    题目传送门 A Horrible Poem 题目描述 Bytie boy has to learn a fragment of a certain poem by heart. The poem, f ...

随机推荐

  1. STM32L476的RTC使用问题记录

    1. 在使用RTC的时间戳,从字面意思是,PC13的上升沿可以触发时间戳的中断函数 /*##-1- Configure the Time Stamp peripheral ############## ...

  2. cogs1713 [POJ2774]很长的信息

    cogs1713 [POJ2774]很长的信息 原题链接 题解 把两串拼成A+'%'+B+'$'.跑后缀数组然后相邻两点i,i+1不在同一串里就用ht[i]更新答案. 好裸... Code // It ...

  3. chrome json 格式化插件 JSON-Handle

    Chrome 浏览器插件安装方法: 在地址栏输入  , 将下载的 .crx 插件包拖放到打开的页面中. JSON-Handle It's a browser and editor for JSON d ...

  4. 一学就会pip换镜像源

    首先介绍一个国内好用的镜像站 阿里云 http://mirrors.aliyun.com/pypi/simple/ 豆瓣 http://pypi.douban.com/simple/ 清华大学 htt ...

  5. JavaScript学习笔记(一)——JS速览

    第一章 JS速览 1 限制时间处理事件 <script> setTomeout(wakeUpUser,5000); function wakeUpUser() { alert(" ...

  6. ES6的新特性(18)——async 函数

    async 函数 含义 ES2017 标准引入了 async 函数,使得异步操作变得更加方便. async 函数是什么?一句话,它就是 Generator 函数的语法糖. 前文有一个 Generato ...

  7. “Hello World!”团队第三周召开的第二次会议

    今天是我们团队“Hello World!”团队第三周召开的第二次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 ...

  8. Alpha版发布 - 感谢有你们

    在本次alpha开发的过程中,很感谢组长王航对我信任,让我统筹大家的工作任务和进度,使我对项目管理有了深刻的理解. 我也要感谢邹双黛,因为我以前很少做文字类的工作,写东西非常生硬,邹双黛即使在有做家教 ...

  9. Java:有关try、catch和finally的学习(供自己参考)

    Java:有关try.catch和finally的学习 在看到书本的时候对finally的介绍是:不论是否在try块中产生异常,都会执行finally.当时对这句话的理解不够深,误以为在try...c ...

  10. 团队项目成员与题目(本地地铁查询app)

    团队名称:Daydreaming团队成员及其特点:张运涛:能快速与团队成员中的每一位进行合作,能全面考虑遇到的问题,善于总结积累.能较好的理解老师与其他人员的想法要求.刘瑞欣:做事果断,善于领导,有想 ...