思路:
对于字符串a,b, (a.size() < b.size()), 考虑对字符串b满足什么条件:
由1、3可知a是b的前后缀,由2知b有一个周期是3,即a.size(),所以b是用多个a拼接而成的,有因为a是b的前后缀,所以a和b的循环节相同,且a,b均恰好由整数个循环节组成。循环节长度 = 字符串长度 - 最大公共前后缀长度。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e6 + 5;
string s[maxn];
int nxt[maxn];
map<string, int> mp;
void getnext(string s){
int j = -1;
nxt[0] = -1;
int n = s.size();
s = ' ' + s;
for(int i = 1; i <= n; i++){
while(j >= 0 && s[i] != s[j + 1]){
j = nxt[j];
}
nxt[i] = j + 1;
j++;
}
}
// void f(vector<int> &a){
// a.push_back(6);
// }
signed main(){
int n;
while(cin >> n){
// cin >> n;
mp.clear();
int res = 0;
for(int i = 1; i <= n; i++){
cin >> s[i];
getnext(s[i]);
int m = s[i].size();
int T = m - nxt[m];
if(m % T != 0){
T = m;//整个字符串也是一个循环节
}
string t = s[i].substr(0, T);
res += mp[t];
mp[t]++;
}
cout << res << '\n';
}
// string s = "666";
// cout << s.size() << '\n';
// getnext(s);
// cout << s.size() << '\n';
// vector<int> a;
// cout << a.size() << '\n';
// f(a);
// cout << a.size() << '\n';
return 0;
}