比赛 NOIP模拟赛by mzx Day2 评测结果 MMMMMMMMMM
题目名称 拯救紫萱学姐 最终得分 0
用户昵称 Hzoi_chairman 运行时间 0.010 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2016-10-20 21:31:53
显示代码纯文本
#include<iostream>
#include<cmath>
#include<map>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define ll long long
int read()
{
    int x,f=1;
    char ch;
    while(ch=getchar(),!isdigit(ch))if(ch=='-')f=-1;
    x=ch-48;
    while(ch=getchar(),isdigit(ch))x=x*10+ch-48;
    return x*f;
}
void write(ll x)
{
	if(x<0)putchar('-'),x=-x;
	int cnt=0;char ch[50];
	while(ch[++cnt]=x%10+48,x/=10);
	while(putchar(ch[cnt]),--cnt);
	putchar('\n');
}
#define maxe 1001000
#define maxn 1001000
struct edge
{
	int t,n;ll d;
}a[maxe];
int len,head[maxn],dp[maxn],fa[maxn][22],cnt=1,D,f[maxn];ll val[maxn][22];;
void insert(int x,int y,ll z)
{
	a[++len].t=y;a[len].d=z;a[len].n=head[x];head[x]=len;
}
#define k a[i].t
void dfs(int x)
{
	for(int i=head[x];i;i=a[i].n)
	{
		if(fa[x][0]==k)continue;
		fa[k][0]=x;
		dp[k]=dp[x]+1;
		val[k][0]=a[i].d;
		dfs(k);
	}
}
#undef k
map<string,int>mp;
ll lca(int x,int y)
{
	ll ans=0;
	if(dp[x]<dp[y])swap(x,y);
	for(int j=D;j>=0;j--)
		if(dp[fa[x][j]]>=dp[y])ans+=val[x][j],x=fa[x][j];//先更新ans,再往上翻 
	if(x==y)return ans;
	for(int j=D;j>=0;j--)
		if(fa[x][j]!=fa[y][j])ans+=val[x][j]+val[y][j],x=fa[x][j],y=fa[y][j];
	return ans+val[x][0]+val[y][0];
}
int main()
{
	freopen("savemzx.in","r",stdin);
	freopen("savemzx.out","w",stdout);
	string s;
	cin>>s;
	int n=s.length();
	for(int i=1;i<n;i++)
	{
		int j=f[i];
		while(j&&s[j]!=s[i])j=f[j];
		if(s[j]==s[i])f[i+1]=j+1;
		else f[i+1]=0;
	}
	for(int i=0;i<n;i++)
	{
		string s1=s.substr(0,i+1);
		if(!mp[s1])mp[s1]=++cnt;
		int x=f[i+1],y=mp[s1];
		if(!x)insert(1,y,(i+1)*(i+1));
		else
		{
			string s2=s.substr(0,x);//因为是前缀,肯定已经处理过了 
			insert(mp[s2],y,(i+1-x)*(i+1-x));
		}
	}
	dp[1]=1;
	dfs(1);
	D=log(n*1.0)/log(2.0);
	for(int j=1;j<=D;j++)
	{
		for(int i=1;i<=cnt;i++)
		{
			fa[i][j]=fa[fa[i][j-1]][j-1];
			val[i][j]=val[fa[i][j-1]][j-1]+val[i][j-1];
		}
	}
	ll j,maxx=0;
	for(int i=1;i<=cnt;i++)
	{
		int x=lca(1,i);
		if(maxx<x)maxx=x,j=i;
	}
	maxx=0;
	for(int i=1;i<=cnt;i++)
	{
		int x=lca(j,i);
		if(maxx<x)maxx=x;
	}
	write(maxx);
//	system("pause");
	fclose(stdin);
	fclose(stdout);
}