Power Strings---字串hash
阿新 • • 發佈:2018-11-12
問題 C: 【雜湊和雜湊表】Power Strings
時間限制: 1 Sec 記憶體限制: 128 MB
提交: 38 解決: 18
[提交] [狀態] [討論版] [命題人:外部匯入]
題目描述
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"
輸入
Each test case is a line of input representing s, a string of printable characters.
輸出
For each s
樣例輸入
abcd aaaa ababab .
樣例輸出
1 4 3
讓你求,嗯,這個串是由最多多少個相同的小字串構成的,
例如aaaa,可以使1個aaaa組成,也可以是兩個aa,也可以是四個a
那麼輸出4,即最多幾個
那麼從最小的長度i = 1開始列舉,只有strlen(a)%i==0,才能恰好組成,否則跳過即可
對於%==0的情況暴力切割出所有的子串(事先hash),判斷能否成立,
一旦出現成立,那麼就是答案,
還有明顯列舉到strlen(a)/2,即可,因為再往後列舉,都不成立的
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int maxn = 1e6+7;
const pll k{1e9+9,1e9+7},p{1e9+7,1e9+9},one{1ll,1ll},zero{0ll,0ll};
pll operator - (pll a,pll b){return make_pair((a.first - b.first + p.first)%p.first,(a.second - b.second + p.second)%p.second);}
pll operator * (pll a,pll b){return make_pair((a.first * b.first)%p.first,(a.second * b.second)%p.second);}
pll operator + (pll a,pll b){return make_pair((a.first + b.first)%p.first,(a.second + b.second)%p.second);}
pll operator + (pll a,int b){return make_pair((a.first + b)%p.first,(a.second + b)%p.second);}
pll Hash(char a[],int len){
pll ans = zero;
for(int i=0;i<len;i++)
ans = ans*k + a[i];
return ans;
}
pll Pow(pll a,int n){
pll ans = one;
while(n){
if(n&1)ans = ans*a;
a = a*a;
n>>=1;
}
return ans;
}
char a[maxn];
pll Len[maxn];
int main(){
while(cin>>a+1){
if(a[1]=='.')break;
Len[0] = zero;
for(int i=1;a[i];i++){
Len[i] = Len[i-1]*k + a[i];
}
int ans = 1,la = (strlen(a+1)+1)/2,ln = strlen(a+1);
for(int i=1;i<=la;i++){
if(ln%i)continue;///一個優化
int flag = 0;
for(int j=i;!flag && j<=ln;j+=i)
if(Len[j]-Len[j-i]*Pow(k,i)!=Len[i])
flag = 1;
if(!flag){
ans = ln/i;
break;///找到即跳出
}
}
cout<<ans<<endl;
}
return 0;
}