比赛 |
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);
}