Colorful String(manacher+序列自動機)

https://nanti.jisuanke.com/t/41389

The value of a string s is equal to the number of different letters which appear in this string.

Your task is to calculate the total value of all the palindrome substring.

Input

The input consists of a single string ∣s∣(1≤∣s∣≤3×105).

The string s only contains lowercase letters.

Output

Output an integer that denotes the answer.

樣例輸入

abac

樣例輸出

6

樣例解釋

abac has palindrome substrings a,b,a,c,aba,ans the total value is equal to 1+1+1+1+2=6。

關於迴文串首先就想到了馬拉車和迴文樹,但是迴文樹並不會改(卑微)所以就考慮馬拉車

我們可以用馬拉車把以該點爲迴文中心的迴文串找出來,那麼這個迴文子串的值是多少呢,肯定不能暴力找,否則一個全a串就給卡掉了。

雖然串可能很長,但是每個迴文串的值最大26,我們可以考慮每個字符對以該點爲迴文中心的迴文串的貢獻

序列自動機預處理出該位置後每個字符第一次出現的位置,從該位置到最大回文半徑都有貢獻(說的不太準確,看代碼應該能懂)然後暴力算一算貢獻就可以了,時間複雜度應該在1e7左右

 

(被簽到題卡成傻逼,心態崩了,編譯器也崩了,真是人機合一了,呵呵)

 

#include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int N=310005;
char s[N];
char a[N*2];
int p[N*2];
int pos[N][27];
int manacher(char s[],int len){
	int l=0;
	a[l++]='$';
	a[l++]='#';
	for(int i=0;i<len;i++){
		a[l++]=s[i];
		a[l++]='#';
	}
	a[l]=0;
	int mx=0,id=0;
	for(int i=0;i<l;i++){
		p[i]=mx>i?min(p[2*id-i],mx-i):1;
		while(a[i+p[i]]==a[i-p[i]]) p[i]++;
		if(i+p[i]>mx){
			mx=i+p[i];
			id=i;
		}
	}
	return l;
}
int main(){
	while(~scanf("%s",s)){
		int len=strlen(s);
		int Len=manacher(s,len);
		for(int i=0;i<26;i++) pos[len][i]=-1;
		for(int i=len-1;i>=0;i--){
			int c=s[i]-'a';
			pos[i][c]=i;
			for(int j=0;j<26;j++){
				if(j==c) continue;
				pos[i][j]=pos[i+1][j];
			}
		}
		ll ans=0;
		for(int i=1;i<Len;i++){ 
		    if(i&1){
		        int cnt=(p[i]-1)>>1;
		        int now=i>>1;
		        for(int j=0;j<26;j++){
		        	if(pos[now][j]!=-1&&pos[now][j]-now<cnt) ans+=cnt-(pos[now][j]-now);
				}
			} 
		    else{
		        int cnt=p[i]>>1;
		        int now=(i>>1)-1;
		        for(int j=0;j<26;j++){
		        	if(pos[now][j]!=-1&&pos[now][j]-now<cnt) ans+=cnt-(pos[now][j]-now);
				}
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章