【CodeChef-TREEPAL】Tree Palindromes(回文自动机)

传送门


题解:

由于一个点下方可能有多个不同的转移,原来的均摊分析在这里就失效了,我们可以存一个to数组表示会跳到哪里,这道题字符集很小,直接做就行了。


#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const

namespace IO{
	inline char get_char(){
		static cs int Rlen=1<<22|1;
		static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++; 
	}
	
	template<typename T>
	inline T get(){
		char c;
		while(!isdigit(c=gc()));T num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return num;
	}
	inline int getint(){return get<int>();}
}
using namespace IO;

using std::cerr;
using std::cout;

cs int N=1e5+5;

std::vector<int> G[N];
inline void addedge(int u,int v){
	G[u].push_back(v);
	G[v].push_back(u);
}

char s[N];int tot;
namespace PAM{
	int son[N][26],to[N][26],fa[N],len[N],now;
	
	inline void init(){
		len[1]=-1,fa[0]=1;now=1;
		for(int re i=0;i<26;++i)to[0][i]=1;
	}
	
	inline int push_back(char c,int p){
		c-='a';
		while(s[tot]!=s[tot-len[p]-1])p=to[p][c];
		if(!son[p][c]){
			len[++now]=len[p]+2;
			int k=fa[p];
			while(s[tot]!=s[tot-len[k]-1])k=to[k][c];
			fa[now]=son[k][c],son[p][c]=now;
			memcpy(to[now],to[k],sizeof to[k]);
			to[now][s[tot-len[fa[now]]]-'a']=fa[now];
		}
		return son[p][c];
	}
}

ll ans=0;

char c[N];
int id[N],mx[N];
void dfs(int u,int p){
	s[++tot]=c[u];
	id[u]=PAM::push_back(c[u],id[p]);
	mx[u]=std::max(mx[p],PAM::len[id[u]]);
	ans+=mx[u];
	for(int re v:G[u])if(v!=p)dfs(v,u);
	--tot;
}

int n;
signed main(){
//	freopen("treepal.in","r",stdin);
	PAM::init();
	scanf("%d",&n);scanf("%s",c+1);s[0]=-1;
	for(int re i=1;i<n;++i)addedge(getint(),getint());
	dfs(1,0);
	cout<<ans<<"\n";
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值