【bzoj2795】[Poi2012]A Horrible Poem hash
2016-03-31 22:27
357 查看
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
HINT
Source
鸣谢 jiangzoi&oimaster枚举约数是根号级的,算算复杂度好像过不了
有一个结论:若k是一个循环节,则pk也是一个循环节
于是把区间长度质因数分解,对于一个素数的指数ai,尽可能让它小,使得它再小就不是循环节为止。枚举指数是log级的。
O1判断是否是循环节可以hash
然后我写了个双hash,不过好像不需要?
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; const int SZ = 1000010; const int mod1 = 1000000007; const int mod2 = 998244353; int pri[SZ]; char s[SZ]; int h1[SZ],h2[SZ],n; int mi1[SZ],mi2[SZ]; int gethash1(int l,int r) { int len = r - l + 1; return (int)((h1[r] - (LL)h1[l - 1] * mi1[len] % mod1 + mod1) % mod1); } int gethash2(int l,int r) { int len = r - l + 1; return (int)((h2[r] - (LL)h2[l - 1] * mi2[len] % mod2 + mod2) % mod2); } bool check(int l,int r,int len) //[l,l + len - 1] [r - len + 1,r] { int x = r - l + 1 - len; int l1 = gethash1(l,l + x - 1),r1 = gethash1(r - x + 1,r); int l2 = gethash2(l,l + x - 1),r2 = gethash2(r - x + 1,r); return l1 == r1 && l2 == r2; } int ask_ans(int l,int r) { int ans = r - l + 1; int x = r - l + 1; for(int i = 2;i * i <= x;i ++) { while(ans % i == 0 && check(l,r,ans / i)) ans /= i; while(x % i == 0) x /= i; } if(x != 1 && check(l,r,ans / x)) ans /= x; return ans; } int main() { scanf("%d",&n); scanf("%s",s + 1); mi1[0] = mi2[0] = 1; for(int i = 1;i <= n;i ++) { mi1[i] = (LL)mi1[i - 1] * 233 % mod1; mi2[i] = (LL)mi2[i - 1] * 10007 % mod2; } for(int i = 1;i <= n;i ++) { h1[i] = ((LL)h1[i - 1] * 233 % mod1 + s[i]) % mod1; h2[i] = ((LL)h2[i - 1] * 10007 % mod2 + s[i]) % mod2; } int q; scanf("%d",&q); while(q --) { int l,r; scanf("%d%d",&l,&r); printf("%d\n",ask_ans(l,r)); } return 0; }
相关文章推荐
- 对手势分发机制的一些理解
- 火车调度问题
- mysql update语句的用法详解
- leetcode_033 Search in Rotated Sorted Array
- 蓝桥杯_算法提高_金明的预算方案(动态规划、01背包变形)
- 【MVC 4】6.SportsSore:导航
- UI复习笔记1
- STL vector,deque,list
- 对委托的初步研究
- python3中的mysql数据库操作
- RxJava中的错误处理
- bzoj 3343: 教主的魔法
- 多态
- Spring框架中IOC和aop
- Java实现微信菜单json字符串拼接
- 中科院
- 一天一个Java基础——泛型
- Synchronize实现原理(很难)
- <result><param></param></result>问题
- Linux_ pipe 匿名管道 浅解