题目
Description
Input
Output
一行,一个四位小数表示最大平均权值。
Sample Input
olaowlaola
3
ol 1
wla 5
ola 3
Sample Output
1.6667
Data Constraint
Hint
最大平均权值是5/3,选“wla”.
思路
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=4e5+77;
ll v[N];
int t[N][26],l[N],fa[N],ct,n,m,le,tp,q[N],va;
double f[N],g[N],mx[N];
char s[N],c[N];
int check(double m)
{
f[1]=mx[1]=-1e9;
for(int i=1; i<=ct; i++)
{
int x=q[i];
for(int j=0,y; j<26; j++)
if(y=t[x][j])
{
f[y]=f[x];
int p=fa[x];
while(!t[p][j])
{
f[y]=max(f[y],f[p]);
p=fa[p];
}
f[y]+=v[fa[y]]-m;
g[y]=g[x]+v[y]-m;
f[y]=max(f[y],g[y]);
if(l[y]==1)f[y]=v[y]-m;
mx[y]=max(f[y],mx[fa[y]]);
}
}
int x=1;
double r=-1e9,r1=-1e9;
for(int i=1,c; i<=n; i++)
{
c=s[i]-'a';
while(!t[x][c]){
r1=max(r1,f[x]);
x=fa[x];
}
x=t[x][c];
r1+=v[x]-m;
r=max(r,max(r1,mx[x]));
}
return r>=0;
}
int main()
{
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
cin>>s+1>>m;
n=strlen(s+1);
ct=1;
for(int i=1; i<=m; i++)
{
cin>>c+1>>va;
int x=1;
le=strlen(c+1);
for(int j=1,v; j<=le; j++)
{
v=c[j]-'a';
if(!t[x][v])t[x][v]=++ct;
x=t[x][v];
}
v[x]+=va;
}
for(int j=0; j<26; j++)
t[0][j]=1;
q[tp=1]=1;
for(int i=1; i<=tp; i++)
{
int x=q[i];
for(int j=0,y; j<26; j++)
if(y=t[x][j])
{
q[++tp]=y;
int p=fa[x];
while(!t[p][j])p=fa[p];
fa[y]=t[p][j];
v[y]+=v[fa[y]];
l[y]=l[x]+1;
}
}
double l=0,r=1e10;
while(r-l>1e-6)
{
double yjy=(l+r)*0.5;
check(yjy)?l=yjy:r=yjy;
}
printf("%.4lf\n",l);
}