GDOI2019 小说

Posted cszmc2004

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GDOI2019 小说相关的知识,希望对你有一定的参考价值。

神题。。。。。

这道题的60分做法是:分答案串<=100和>100讨论。

<=100的部分可以使用算法3解决。枚举一个点l表示现在要统计左端点l~l+99所有前缀字符串的密度的最大值。可以使用ac自动机解决

>100的部分可以二分+ac自动机。

原问题实际上是一个分数规划问题。假设选了i个物品,编号a[1],a[2]...a[i],则平均值是$frac{a[1]+a[2]+....+a[i]}{i}$

如果设一个二分值mid,判定答案是否>=mid,则实际上是判定$a[1]-md+a[2]-md+...+a[i]-md>=0$,实际上就是选一个位置有md的代价,要求最大值。

使用dp解决。设f[i]表示i结尾的串,长度要>100的最大价值。ans[i]表示i-99~i的以i结尾的子串价值的最大值,st[i]表示ac机上以i结尾的串的价值,ans可以使用算法3计算。

f的转移有点像最大子段和。设v表示1~i-100的前缀最大价值,则v=max(v+st[i-100]-md,0),表示枚举是否选i-100这个点。

f[i]=max(f[i],v+ans[i]-100*md)表示使用i-99~i和1~i-100的最大价值组合答案。

只需要判定max(f[1~n])是否>=0即可。

核心代码:

int ck(double md){
    double r=-1e18,v=0;
    for(int i=100;i<n;i++){
        v=max(v+st[i-100]-md,0.0);
        r=max(r,v+ans[i]-100.0*md);
    }
    return r>=0;
}
double va=0;
for(int i=0;i<n;i++){
    int x=0,ss=0;
    for(int j=i;j<min(i+100,n);j++){
        x=a.c[x][s[j]-a];
        ss+=a.f[x];
        va=max(va,ss/((double)j-i+1));
    }
    if(i+99<n)ans[i+99]=ss;
}
int x=0;
for(int i=n-1;i;i--){
    x=b.c[x][s[i]-a];
    st[i]=b.f[x];
}
double l=0,r=1000000000;
while(l+1e-6<r){
    double md=(l+r)*0.5;
    if(ck(md))l=md;
    else r=md;
}
printf("%.4lf
",max(l,va));

 

以上是关于GDOI2019 小说的主要内容,如果未能解决你的问题,请参考以下文章

[jzoj 6084] [GDOI2019模拟2019.3.25] 礼物 [luogu 4916] 魔力环 解题报告(莫比乌斯反演+生成函数)

课外阅读亮剑小说片段 毕业论文

Visual Studio 2012-2019的130多个jQuery代码片段。

小说爬虫

;~ 小部分AutoHotkey源代码片段测试模板2019年10月9日.ahk

三色GDOI