[POI2012]OKR-A Horrible Poem hash
题面:洛谷
题解:
首先我们需要知道一个性质,串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的更多相关文章
- 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】[Poi2012]A Horrible Poem hash
[BZOJ2795][Poi2012]A Horrible Poem Description 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串 ...
- 【bzoj2795】[Poi2012]A Horrible Poem Hash+分解质因数
题目描述 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. 输入 第一行一个正整数n (n<= ...
- bzoj 2795 [Poi2012]A Horrible Poem hash+线性筛
题目大意 bzoj 2795 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节. 如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. n<=500 ...
- BZOJ2795&2890&3647[Poi2012]A Horrible Poem——hash
题目描述 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. 输入 第一行一个正整数n (n<= ...
- 【bzoj2795】【Poi2012】A Horrible Poem
题解: 询问区间的整循环节 设区间长度为$n$ 如果有循环节长为$x$和$y$,那由斐蜀定理得$gcd(x,y)$也一定为一个循环节: 假设最小的循环节长为$mn$,那么对于任何循环节长$x$,一定$ ...
- P3538 [POI2012]OKR-A Horrible Poem
P3538 [POI2012]OKR-A Horrible Poem hash+线性筛 题解 <----这篇写的不错(其实是我懒得码字了qwq) UVA10298 Power Strings 的 ...
- 洛谷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 ...
随机推荐
- 【MYSQL用户创建报错】ERROR 1396 (HY000): Operation CREATE USER failed for 'user1'@'%'
原文参考自:http://blog.csdn.net/u011575570/article/details/51438841 1.创建用户的时候报错ERROR 1396 (HY000): Operat ...
- JS 中屏幕、浏览器和文档的高度、宽度和距离
1.各种对象 window.screen - 屏幕,window - 窗口,document.documentElement & document.body.parentNode - 文档,d ...
- Nginx高性能优化
#Nginx配置文件优化 worker_processes ; # nginx进程数,建议按照cpu数目来指定,一般为它的倍数. worker_cpu_affinity ; # 为每个进程分配CPU的 ...
- Oracle数据库及图形化界面安装教程详解
百度云盘oracle数据库及图形化界面安装包 链接: https://pan.baidu.com/s/1DHfui-D2n1R6_ND3wDziQw 密码: f934 首先在电脑D盘(或者其他不是C盘 ...
- 5.airflow问题
1. Traceback (most recent call last): File "/usr/bin/airflow", line 28, in <module> ...
- es6 babel编译
本文主要参照阮一峰的es6入门,为提高自己写了一份随笔. 原文地址请戳这里 ECMAScript 6 入门 ECMAScript 6是JavaScript语言的下一代标准.因为当前版本的ES6是在2 ...
- mysql数据库工具
1.navicat12 中文版及破解 链接:https://pan.baidu.com/s/1TH8m6lduHJybUGhmjFPIAA 提取码:kwcd 2.旧版本mysql-front(连接可选 ...
- 【每日scrum】NO.9
(1)这是我们冲刺的最后一天,晚上我们的团队进行了收尾工作:第一阶段的任务基本完成,软件主要实现了校园景点照片以及对应的介绍,查询最短路径,查询涉及相关景点的查询,查询全部路径,基本界面的设计,导航功 ...
- 2016-2017 ACM-ICPC, NEERC, Northern Subregional Contest Problem I. Integral Polygons
题目来源:http://codeforces.com/group/aUVPeyEnI2/contest/229510 时间限制:2s 空间限制:256MB 题目大意: 给定一个凸多边形,有一种连接两个 ...
- Hibernate:工作原理
Hibernate的工作原理图如下所示: