poj 2406 Power Strings
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 41250 | Accepted: 17150 |
Description
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).
Input
Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.
Output
For each s you should print the largest n such that s = a^n for some string a.
Sample Input
abcd
aaaa
ababab
.
Sample Output
1
4
3
Hint
This problem has huge input, use scanf instead of cin to avoid time limit exceed.
Source
题解:
本来想找后缀数组的题,发现可以用hash来O(n)解决。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 #include<cstring> 7 #include<queue> 8 #include<vector> 9 using namespace std; 10 typedef unsigned long long ULL; 11 const ULL BASE=127; 12 const int maxn=2000000; 13 char s[maxn]; 14 int len; 15 ULL base[maxn],hash[maxn]; 16 inline ULL get_hash(int l,int r){ 17 return hash[r]-hash[l-1]*base[r-l+1]; 18 } 19 int main(){ 20 base[0]=1; for(int i=1;i<=1000000;i++) base[i]=base[i-1]*BASE; 21 for(;;){ 22 scanf("%s",s+1); len=strlen(s+1); 23 if(s[1]=='.') break; 24 for(int i=1;i<=len;i++) hash[i]=hash[i-1]*BASE+s[i]-'a'+1; 25 bool vis=false; 26 for(int i=len-1;i>=1;i--){ 27 if(get_hash(1,i)==get_hash(len-i+1,len)&&len%(len-i)==0){ 28 vis=true; 29 printf("%d\n",len/(len-i)); 30 break; 31 } 32 } 33 if(vis==false) puts("1"); 34 } 35 return 0; 36 }