Power Strings---字符串hash

xiaoxiao2025-06-24  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". 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).

输入

 Each test case is a line of input representing s, a string of printable characters.

输出

 For each s you should print the largest n such that s = a^n for some stringa. 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.

样例输入

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; }

 

转载请注明原文地址: https://www.6miu.com/read-5032433.html

最新回复(0)