zoukankan      html  css  js  c++  java
  • Crossword Expert CodeForces

    大意: $n$个题, 按照第$i$题随机$t_i$或$t_i+1$秒钟完成, 最多做$T$秒, 求做题数期望.

     

    期望转为做题数$ge x$的方案数之和最后再除以总方案数

    这是因为$sumlimits_{x}x{cnt}_x=sumlimits_{x}sumlimits_{yge x}{cnt}_y$

    然后得到对于$x$的贡献为$2^{n-x}sumlimits_{k=0}^{min(x,T-s[x])}inom{x}{k}$

    上面的和式中$k$最大值关于$x$是递减的, 可以逆序枚举$x$, $O(1)$将$suminom{x+1}{k}$转移到$suminom{x}{k}$.

    复杂度就为$O(n)$.

    #include <iostream>
    #include <cstdio>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define PER(i,a,n) for(int i=n;i>=a;--i)
    using namespace std;
    typedef long long ll;
    const int P = 1e9+7, inv2 = (P+1)/2;
    ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
    const int N = 1e6+10;
    int n,a[N],fac[N],ifac[N],po[N];
    ll T,s[N];
    int C(ll n, ll m) {
    	if (n<m) return 0;
    	return (ll)fac[n]*ifac[m]%P*ifac[n-m]%P;
    }
    
    int main() {
    	fac[0]=ifac[0]=po[0]=1;
    	REP(i,1,N-1) po[i]=po[i-1]*2ll%P;
    	REP(i,1,N-1) fac[i]=(ll)fac[i-1]*i%P;
    	ifac[N-1]=inv(fac[N-1]);
    	PER(i,1,N-2) ifac[i]=(ll)ifac[i+1]*(i+1)%P;
    	scanf("%d%lld", &n, &T);
    	REP(i,1,n) scanf("%d",a+i),s[i]=s[i-1]+a[i];
    	int ans = 0, ret = 0, pre = -1;
    	PER(i,1,n) if (s[i]<=T) {
    		int mx = i;
    		if (T-s[i]<mx) mx = T-s[i];
    		if (!mx) ret = 1;
    		else if (pre>mx) ret = po[i];
    		else {
    			REP(j,pre+1,mx) ret = (ret+C(i+1,j))%P;
    			ret = (ret+C(i,mx))*(ll)inv2%P;
    		}
    		ans = (ans+(ll)ret*po[n-i])%P;
    		pre = mx;
    	}
    	ans = (ll)ans*inv(po[n])%P;
    	if (ans<0) ans += P;
    	printf("%d
    ", ans);
    }
    
  • 相关阅读:
    Springboot websocket学习Demo
    webpack与vue使用
    图片服务器图片剪切处理
    时间字段设置默认值
    函数的递归
    数据类型检测及封装
    隔行变色
    if-else案例–开关灯
    作用域
    数据类型核心操作步骤和原理
  • 原文地址:https://www.cnblogs.com/uid001/p/11187919.html
Copyright © 2011-2022 走看看