• [Luogu P6059]纯粹容器 senpai


    题目链接:Luogu P6059

    我傻了,比赛时写错了一个小细节,一看(nle 50)还以为想假了

    先把最大的(a_i)特判掉,答案显然为(n-1)

    我们枚举每一个(a_i)分别计算答案,找到左右距(a_i)最近且大于(a_i)(a_l,a_r),那么(a_i)被击倒只有([l,i])或者([i,r])间的容器全部进行决斗。

    (若(a_l)(a_r)在此之前和其他容器决斗只可能不变或变得更大)

    枚举(a_i)在第(j)轮被淘汰,设概率为(p_{i,j}),则(a_i)的期望存活轮数为(sum_{1le j<n}limits p_{i,j}*(j-1))

    考虑怎么求(p_{i,j}),设(g_{i,j})表示(a_i)(j)的某一次被淘汰的概率,则(p_{i,j}=g_{i,j}-g_{i,j-1})

    因为一共进行了(n-1)次决斗,设(Calc(i,j))表示在这(n-1)轮决斗中选出(i)轮决斗全部在前(j)轮的概率

    那么对于(g_{i,j}),要么被左边淘汰,要么被右边淘汰,容斥一下则

    (g_{i,j}=Calc(i-l,j)+Calc(r-i,j)-Calc(r-l,j))

    (被左边淘汰的概率+被右边淘汰的概率-去掉两边决斗全部在前(j)场的重复计算)

    当然如果某一边没有比(a_i)大的容器那答案就是(Calc(i-l,j))或者(Calc(r-i,j))

    考虑计算(Calc(i,j))(i)场在前(j)场的方案数:(A_j^i=frac{j!}{(j-i)!}),其他决斗的方案数:((n-1-i)!),总方案数:((n-1)!)

    (Calc(i,j)=frac{j!(n-1-i)!}{(j-i)!(n-1)!})

    预处理阶乘及逆元,暴力计算即可做到(O(n^2)),不知道能不能继续优化,反正O(n^2)足够了

    时间复杂度 (O(n^2))

    空间复杂度 (O(n))

    代码:

    #include <cstdio>
    typedef long long ll;
    
    const int N=55,P=998244353;
    int n,a[N],Fac[N],Inv[N],Ans[N];
    
    ll Pow(ll a,int b,ll s=1){for(;b;b>>=1,a=a*a%P)if(b&1)s=s*a%P;return s;}
    
    inline int Calc(int x,int l)//x场全部在前l场的概率
    {
        if(x>l)return 0;
        return (ll)Fac[l]*Inv[l-x]%P*Fac[n-1-x]%P*Inv[n-1]%P;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=Fac[0]=1;i<=n;++i)Fac[i]=(ll)Fac[i-1]*i%P;
        Inv[n]=Pow(Fac[n],P-2);
        for(int i=n;i>=1;--i)Inv[i-1]=(ll)Inv[i]*i%P;
        for(int i=1;i<=n;++i)scanf("%d",&a[i]);
        for(int i=1;i<=n;++i)
        {
            int l=i-1,r=i+1;
            while(l>=1&&a[l]<a[i])--l;
            while(r<=n&&a[r]<a[i])++r;
            if(l<1&&r>n){Ans[i]=n-1;continue;}
            int Res=0,Pp=0;
            for(int j=1;j<n;++j)
            {
                int Np=0;
                if(l>=1)Np=Calc(i-l,j);
                if(r<=n)Np=(Np+Calc(r-i,j))%P;
                if(l>=1&&r<=n)Np=(Np-Calc(r-l,j)+P)%P;//容斥
                Res=(Res+ll(j-1)*(Np-Pp+P))%P,Pp=Np;//这里没有p和g数组,Np代表g_{i,j},Pp代表g_{i,j-1}
            }
            Ans[i]=Res;
        }
        for(int i=1;i<=n;++i)printf("%d%c",Ans[i],i==n?'
    ':' ');
        return 0;
    }
    
  • 相关阅读:
    properties文件不能输入中文
    java: bin里面的.class文件没有了怎么办
    LINUX 系统java自动化启动浏览器 提示:The driver is not executable: /home/pt/Downloads/googledriver/chromedriver_linux64/chromedriver
    MarkdownTest
    洛谷P5364 [SNOI2017]礼物 题解
    长链剖分
    左偏树(可并堆)
    Splay
    分层图最短路
    整体二分
  • 原文地址:https://www.cnblogs.com/LanrTabe/p/12259391.html
Copyright © 2020-2023  润新知