记录编号 377827 评测结果 AAAAAAAAAAAA
题目名称 2622.[HZOI 2016][NBUT 1653]String in the tree 最终得分 100
用户昵称 半汪 是否通过 通过
代码语言 C++ 运行时间 0.755 s
提交时间 2017-03-02 16:29:00 内存使用 0.98 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned int TYPE;
const int maxn=10010;
const TYPE H=1000007;
int T,N,tot,son[maxn][2],hkey[maxn],ans[maxn],fa[maxn],Rt,deep[maxn],goat,head[maxn];
ll tag[maxn],nowl,nowr;
TYPE Hash[maxn],Pow[maxn];
char ch[maxn];
#define L(x) son[x][0]
#define R(x) son[x][1]
struct Edge{
	int to,next,w;
}edge[maxn*2];
void Add(int x,int y){
	edge[++tot].to=y;
	edge[tot].next=head[x];
	head[x]=tot;
}
int pre,scn,h1,h2;
#define p edge[i].to
void rebuild(int x,ll l,ll r){
	if(!x)return;
	tag[x]=(l+r)/2;
	ll mid=(l+r)/2;
	if(L(x))rebuild(L(x),l,mid);
	if(R(x))rebuild(R(x),mid,r);
}
int rotate(int x,int k,ll l,ll r){
	int y=son[x][k^1];
	son[x][k^1]=son[y][k];
	son[y][k]=x;
	rebuild(y,l,r);
	return y;
}
int rotate(int x,int k){
	int y=son[x][k^1];
	son[x][k^1]=son[y][k];
	son[y][k]=x;
	return y;
}
bool dcmp(int x,int y){
	return (ch[x]<ch[y]||(ch[x]==ch[y]&&tag[fa[x]]<tag[fa[y]]));
}
void insert(int &rt,int x,ll l,ll r){
	if(!rt){
		rt=x;
		tag[x]=(l+r)/2;
		L(x)=R(x)=0;hkey[x]=rand()%10000000+1;
		return;
	}
	ll mid=(l+r)>>1;
	if(dcmp(x,rt))insert(L(rt),x,l,mid);
	else insert(R(rt),x,mid,r);
	if(L(rt)&&hkey[L(rt)]<hkey[rt])rt=rotate(rt,1,l,r);
	else if(R(rt)&&hkey[R(rt)]<hkey[rt])rt=rotate(rt,0,l,r);
}
int query_pre(int x){
	int now=Rt,maxid=0;
	while(now){
		if(dcmp(now,x)){
			if(!maxid||tag[now]>tag[maxid])maxid=now;
			now=R(now);
		}
		else now=L(now);
	}
	return maxid;
}
int query_scn(int x){
	int now=Rt,minid=0;
	while(now){
		if(dcmp(x,now)){
			if(!minid||tag[now]<tag[minid])minid=now;
			now=L(now);
		}
		else now=R(now);
	}
	return minid;
}
bool check(int x,int y,int len){
	if(Hash[x]-Hash[x-len]*Pow[len]==Hash[y]-Hash[y-len]*Pow[len])return 1;
	return 0;
}
int erase(int rt,int x,ll l,ll r){
	ll mid=(l+r)>>1;
	if(rt==x){
		if(!L(rt)){
			rebuild(R(rt),l,r);
			return R(rt);
		}
		if(!R(rt)){
			rebuild(L(rt),l,r);
			return L(rt);
		}
		if(hkey[L(rt)]<hkey[R(rt)])rt=rotate(rt,1),R(rt)=erase(R(rt),x,mid,r);
		else rt=rotate(rt,0),L(rt)=erase(L(rt),x,l,mid);
		goat=rt;nowl=l;nowr=r;
	}
	else if(tag[rt]<tag[x])R(rt)=erase(R(rt),x,mid,r);
	else L(rt)=erase(L(rt),x,l,mid);
	return rt;
}
int LCP(int x,int y){
	int l=1,r=min(x,y),maxx=0;
	while(l<=r){
		int mid=(l+r)>>1;
		if(check(x,y,mid)){
			maxx=max(maxx,mid);
			l=mid+1;
		}
		else r=mid-1;
	}
	return maxx;
}
void check(){
	cout<<"root"<<Rt<<endl;
	for(int i=1;i<=N;i++){
		cout<<i<<" "<<tag[i]<<" "<<L(i)<<" "<<R(i)<<endl;
	}
}
void dfs(int x){
	Hash[deep[x]]=Hash[deep[x]-1]*H+ch[x]-'a';
	pre=query_pre(x),scn=query_scn(x);
	if(pre)h1=LCP(deep[pre],deep[x]);else h1=0;
	if(scn)h2=LCP(deep[scn],deep[x]);else h2=0;
	insert(Rt,x,0,(1ll<<61));
//	cout<<x<<" * "<<pre<<" "<<scn<<" "<<h1<<" "<<h2<<endl;
	ans[x]=ans[fa[x]]+deep[x]-max(h1,h2);
	for(int i=head[x];i;i=edge[i].next){
		if(p==fa[x])continue;
		deep[p]=deep[x]+1;
		fa[p]=x;
		dfs(p);
	}
	goat=0;
//	cout<<"erase"<<x<<endl;	
//	cout<<"**"<<Rt<<endl;
	Rt=erase(Rt,x,0,(1ll<<61));
//	check();
	if(goat)rebuild(goat,nowl,nowr);
}
void init(){
	scanf("%d",&N);
	memset(head,0,sizeof(head));
	tot=0;
	for(int i=1;i<N;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		Add(x,y);Add(y,x);
	}
	scanf("%s",ch+1);
	deep[1]=1;fa[1]=0;
	dfs(1);
	for(int i=1;i<=N;i++)printf("%d\n",ans[i]);
}
int main(){
	freopen("balsuffix.in","r",stdin);freopen("balsuffix.out","w",stdout); 
	srand(665543);
	scanf("%d",&T);
	Pow[0]=1;
	for(int i=1;i<=10000;i++)Pow[i]=Pow[i-1]*H;
	while(T--){
		init();
	}
     return 0;
 }