zoukankan      html  css  js  c++  java
  • Codeforces 1194F. Crossword Expert

    传送门

    考虑每一个位置的期望贡献 $P[i]$

    对于第 $k$ 个位置,设 $sum=sum_{i=1}^{k}t[k]$,那么 $T-sum$ 即为用最短时间完成完位置 $k$ 后多出来的空闲时间

    如果 $T-sum>=k$ 那么这个位置一定能完成,贡献为 $1$

    如果 $T<sum$ ,那么这个位置一定没法完成,贡献为 $0$

    否则设 $mx=max(T-sum,k)$,那么这个位置完成的总情况数就是在多出来的时间内任选几个位置多花费 $1$

    那么这个位置有 $sum_{i=0}^{mx} inom {mx}{i} $ 种不同的合法方案,再除以总方案数 $2^k$ 即为概率

    因为价值为 $1$,那么期望贡献 $P[i]$ 就是 $frac {1} {2^k} sum_{i=0}^{mx} inom {mx}{i} $

    然后发现直接计算一堆组合数的复杂度是 $n^2$ 的,考虑如何优化计算过程

    注意到我们每次算组合数时的 $inom {mx} {i} $ 的 $mx$ 是单调递减的(显然只要考虑 $T-sum<k$ 时的情况),并且每次 $i$ 加一

    考虑杨辉三角递推组合数时,$2sum_{j=0}^{x}inom {i}{j}=(sum_{j=0}^{x}inom {i+1}{j})+inom {i}{x}$(这个自己画一下杨辉三角就知道了)

    那么我们就可以动态维护 $now=sum_{i=0}^{mx} inom {mx}{i}$,然后每到下一层就 $now=now*2-inom {i-1}{mx_{i-1}}$

    然后再利用 $mx$ 的单调性直接暴力维护一下 $now$ 即可做到 $O(n)$

    然后就过了,注意 $long long$

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=4e5+7,mo=1e9+7;
    inline int fk(int x) { return x>=mo ? x-mo : x; }
    int n,t[N],fac[N],finv[N],ans;
    ll T;
    inline int ksm(int x,int y)
    {
        int res=1;
        while(y) { if(y&1) res=1ll*res*x%mo; x=1ll*x*x%mo; y>>=1; }
        return res;
    }
    inline int C(int x,int y) { return 1ll*fac[x]*finv[y]%mo*finv[x-y]%mo; }
    int main()
    {
        n=read(); T=read();
        fac[0]=1; finv[0]=1;
        for(int i=1;i<=n;i++)
        {
            t[i]=read();
            fac[i]=1ll*fac[i-1]*i%mo;
            finv[i]=ksm(fac[i],mo-2);
        }
        int i2=1,now=0,pre=0; ll sum=0;
        for(int i=1;i<=n;i++)
        {
            sum+=t[i]; i2=fk(i2+i2);
            if(T-sum>=i) { ans++; continue; }
            if(T-sum<0) break;
            int mx=T-sum;
            if(!now)
            {
                for(int j=0;j<=mx;j++) now=fk(now+C(i,j));
                pre=mx; ans=fk(ans+1ll*now*ksm(i2,mo-2)%mo);
                continue;
            }
            now=fk( fk(now+now)-C(i-1,pre)+mo );
            while(pre>mx) now=fk(now-C(i,pre)+mo),pre--;
            ans=fk(ans+1ll*now*ksm(i2,mo-2)%mo);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    支付宝校园一卡通充值服务体验
    商品筛选导航菜单亮点欣赏
    手机QQ v4.2 有感
    因所缺,而所需——互联网应用的开发方向
    浅谈 css3 box盒子模型以及box-flex的使用
    浅谈stylus与sass的对比
    css3 transfrom使用以及其martix(矩阵)属性与其它属性的关系
    js命名空间
    公用的stringUtil工具
    js 实现angylar.js view层和model层双绑定(改变view刷新 model,改变model自动刷新view)
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11603481.html
Copyright © 2011-2022 走看看