Gym - 100548G The Problem to Slow Down You

 

 

    依然是回文树。

    我们只需要吧siz[]改成统计两边的siz[][0/1],然后把两个字符中间随便加一个不会出现的字符拼起来,做一遍回文树统计一下就OJBK了

 

#include<bits/stdc++.h>
#define ll unsigned long long
using namespace std;
const int maxn=500005;

int T,n,len[maxn],sum[maxn][2],zt,m,p;
int ch[maxn][27],fl[maxn],cnt,now,c;
char s[maxn];
ll ans;

inline void init(){
	ans=zt=0,fill(s,s+n+1,0);
	for(int i=0;i<=cnt;i++) memset(ch[i],0,sizeof(ch[i]));
	for(int i=0;i<=cnt;i++) sum[i][0]=sum[i][1]=0;
	fill(len,len+cnt+1,0);
	fill(fl,fl+cnt+1,0);
}

inline void solve(){
	fl[0]=1,len[1]=-1,cnt=now=1;
	
	for(int i=1;i<=n;i++,now=ch[now][c],sum[now][zt]++){
		if(i>m) zt=1; c=s[i]-'a';
		
		for(;s[i-len[now]-1]!=s[i];now=fl[now]);
		
		if(!ch[now][c]){
			ch[now][c]=++cnt;
			len[cnt]=len[now]+2;
			
			if(len[cnt]==1) continue;
			
			p=fl[now];
			for(;s[i-len[p]-1]!=s[i];p=fl[p]);
			fl[cnt]=ch[p][c];
		}
	}
	
	for(int i=cnt;i>=2;i--){
		sum[fl[i]][0]+=sum[i][0];
		sum[fl[i]][1]+=sum[i][1];
		ans+=sum[i][0]*(ll)sum[i][1];
	}
}

int main(){
	scanf("%d",&T);
	for(int o=1;o<=T;o++){
		init();
		
		scanf("%s",s+1),s[0]='?',m=strlen(s+1);
		s[m+1]='z'+1,scanf("%s",s+m+2),n=strlen(s+1);
		
		solve(),printf("Case #%d: %I64u\n",o,ans);
	}
	
	return 0;
}

  

posted @ 2018-06-22 16:09  蒟蒻JHY  阅读(374)  评论(0编辑  收藏  举报