P3449-[POI2006]PAL-Palindromes【結論題,字符串hash】

正題

題目鏈接:https://www.luogu.com.cn/problem/P3449


題目大意

nn個迴文串,求有多少對迴文串有序拼接可以形成一個新的迴文串。


解題思路

結論:當兩個迴文串的最短循環節相同時兩個拼接起來就是一個新的迴文串。

這裏感性證明一下:

  1. 若兩個迴文串的最短循環節相同,那麼這個循環節一定也是個迴文串,那麼若干個相同的迴文串拼接那麼這也一定是個迴文串,所以這是充分條件。
  2. 若兩個迴文串的最短循環節不同,那麼頭尾的第一個循環節之中必定有一個位置不同,所以這是必要條件。
  3. 感性理解

所以我們用字符串hashhash判斷即可。


codecode

#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);
} 
發佈了891 篇原創文章 · 獲贊 56 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章