zoukankan      html  css  js  c++  java
  • 20201023模拟赛总结

    T1

    DP

    T2

    头一次在比赛中做出来数论题qwq

    写完 T1 看 T2 ,看见是数学题直接自闭。看完 T3 T4 发现后面的题更自闭滚回来看 T2 。

    首先试图定义 dp[i][j][k] 为比了 (i) 场,平了 (j) 场,赢了 (k) 场的期望得分,然后发现数据范围 (n leq 2000) 给自己期望一个 (0pts) ,当场自闭。

    又试图搞别的方法,定义 f[i][j] 为比了 i 场,平了 j 场的概率,g[i][j] 为在非平局的 i 场中获胜 j 场的概率,那么可以推出当平了 i 场的时候对答案的贡献是 ((i+1) imes f_i imes sumlimits_{j>n-i-j}g_{n-i,j}) ,最终答案即为 (sumlimits_{i=0}^n left[(i+1) imes f_i imes sumlimits_{j>n-i-j}g_{n-i,j} ight])

    在推 (f)(g) 的递推式的时候发现好复杂,又逐渐自闭……

    我们可以找到直接推出 (f_{i,j}) 的方法 : (f_{i,j} = C_i^j imesleft(frac{p}{p+2} ight)^j imes left(frac{2}{p+2} ight)^{i-j})

    但是发现 (g) 的式子并不是很好推,然而突然发现这里两个人获胜的概率是相同的,因此可以想到一个人赢比输少与输比赢少的概率应当是相同的,要注意当 (2mid i) 的时候,可以出现输赢次数相同的情况,我们将这种情况的概率减掉再除以二,其余情况直接返回 (frac{1}{2}) 即可。

    我们只需要枚举平局的数量,即可线性求出答案。

    code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define ll long long
    #define prev Prev
    using namespace std;
    
    int read()
    {
    	int a = 0,x = 1;char ch = getchar();
    	while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
    	while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
    	return a*x;
    }
    
    const int N=3e6+7,P=998244353;
    
    int n,p;
    ll prev;
    ll tmp[N],rev[N];
    
    ll fpow(ll a,ll x)
    {
    	if(x == 1) return a;
    	if(x == 0) return 1;
    	ll t = fpow(a,x/2);
    	if(x&1) return t*t%P*a%P;
    	else return t*t%P;
    }
    ll f[N],g[N],h[N];
    inline ll C(int a,int b) {return b?tmp[a]*rev[b]%P*rev[a-b]%P:1;}
    inline ll F(int i,int j) {return C(i,j)*f[j]%P*g[i-j]%P;}
    inline ll G(int x)
    {
    	if(!x) return 0;
    	if(x&1) return rev[2];
    	else return (1-C(x,x/2)*h[x]%P+P)%P*rev[2]%P;
    }
    
    int main()
    {
    	freopen("fight.in","r",stdin);
    	freopen("fight.out","w",stdout);
    	n = read(),p = read();
    	prev = fpow(p+2,P-2);
    	tmp[0] = rev[0] = f[0] = g[0] = h[0] = rev[1] = 1;
    	for(register int i = 2;i <= n;i ++) {rev[i] = (P-P/i)*rev[P%i];if(rev[i]>P) rev[i]%=P;}
    	for(register int i = 1;i <= n;i ++) {tmp[i] = tmp[i-1]*i;rev[i] = rev[i-1]*rev[i];if(tmp[i]>P)tmp[i]%=P;if(rev[i]>P)rev[i]%=P;}
    	for(register int i = 1;i <= n;i ++) {
    		f[i] = f[i-1]*p%P*prev%P;
    		g[i] = g[i-1]*2%P*prev%P;
    		h[i] = h[i-1]*rev[2]%P;
    	}
    	ll ans = 0;
    	for(register int i = 0;i <= n;i ++) {
    		ans = (ans+F(n,i)*G(n-i)%P*(i+1)%P)%P;
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    centos7 修复引导
    Django 过滤器
    Django 面向对象orm
    Django models字段查询谓词表
    linux常用的监控命令
    常用SQL语句
    python实现FTP服务器
    用python做一个图片验证码
    rsync
    jsonp的理解
  • 原文地址:https://www.cnblogs.com/nao-nao/p/13865780.html
Copyright © 2011-2022 走看看