正題
題目鏈接:https://www.luogu.com.cn/problem/P3449
題目大意
個迴文串,求有多少對迴文串有序拼接可以形成一個新的迴文串。
解題思路
結論:當兩個迴文串的最短循環節相同時兩個拼接起來就是一個新的迴文串。
這裏感性證明一下:
- 若兩個迴文串的最短循環節相同,那麼這個循環節一定也是個迴文串,那麼若干個相同的迴文串拼接那麼這也一定是個迴文串,所以這是充分條件。
- 若兩個迴文串的最短循環節不同,那麼頭尾的第一個循環節之中必定有一個位置不同,所以這是必要條件。
- 感性理解
所以我們用字符串判斷即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define ll long long
#define ull unsigned long long
using namespace std;
const ll N=2e6+10,p=131;
ll n,l,ans;
ull pow[N],hash[N];
char s[N];
map<ull,ll> v;
ll get_hash(ll l,ll r){
if(l>r) return 0;
return hash[r]-hash[l-1]*pow[r-l+1];
}
int main()
{
scanf("%lld",&n);
pow[0]=1;
for(ll j=1;j<=2e6;j++)
pow[j]=pow[j-1]*p;
for(ll i=1;i<=n;i++){
scanf("%lld%s",&l,s+1);
for(ll j=1;j<=l;j++)
hash[j]=hash[j-1]*p+s[j]-'a';
for(ll j=1;j<=l;j++)
if((!(l%j))&&get_hash(1,l-j)==get_hash(j+1,l)){
ll &z=v[hash[j]];
ans+=2*z+1;z++;
break;
}
}
printf("%lld",ans);
}