2020杭电多校 5I / HDU 6822 - Paperfolding (数学)

HDU 6822 - Paperfolding


题意

将一张纸折\(n\)次,四个方向都可以折

折完后取中点,横竖分别切一刀(切十字)

问最后纸被分成的数量的期望(模\(998244353\)




思路

可以发现,从左往右与从右往左对答案的影响相同

同理从上往下和从下往上也是相同的

所以四种情况可以合成等概率的两种情况考虑(横向与竖向)

可以发现,如果往同一个方向折\(k\)次,对于展开后的纸张在对应方向会出现\(2^k\)条割线,那么纸将会被分为\(2^k+1\)

假如当前纸总共要折\(n\)次,横向折\(k\)次,竖向则是\(n-k\)

所以此时纸张会被分成\((2^k+1)*(2^{n-k}+1)\)

考虑到概率,对于“总共要折\(n\)次,横向折\(k\)次”,也就是在所有折的次数中取\(k\)次是横向折的,所以出现的次数可以表示成\(C_{n}^{k}\)

又因为折法总共分成了横向与竖向,所以总共的情况数为\(2^n\)

故期望值就是\(\sum_{k=0}^{n}\frac{C_n^k(2^k+1)(2^{n-k}+1)}{2^n}\)

先只考虑分子部分

将两个多项式合并,得到\((2^n+1+2^k+2^{n-k})\)

先考虑\(\sum_{k=0}^nC_n^k(2^n+1)\)

由于\(\sum_{k=0}^nC_n^k=2^n\),所以该部分等价于\(2^n(2^n+1)\)

考虑\(\sum_{k=0}^nC_n^k(2^k+2^{n-k})\)

分别乘上\(1^{n-k}\)以及\(1^k\)

得到\(\sum_{k=0}^n(C_n^k2^k1^{n-k}+C_n^k2^{n-k}1^k)\)

合并二项式,得到\((2+1)^n+(2+1)^n=2\times3^n\)

所以整个期望值式子便化简到了\(\frac{2^n(2^n+1)+2\times3^n}{2^n}=2^n+1+2\times\frac{3^n}{2^n}\)

快速幂加逆元即可




代码

(202ms/1000ms)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;

ll qpow(ll a,ll n){
    ll r=1;
    a%=mod;
    while(n)
    {
        if(n&1)
            r=(r*a)%mod;
        n>>=1;
        a=(a*a)%mod;
    }
    return r;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ll n;
        scanf("%lld",&n);
        ll n2=qpow(2,n),n3=qpow(3,n),inv2=qpow(n2,mod-2);
        printf("%lld\n",(n2+1+2*n3*inv2)%mod);
    }
    return 0;
}

posted @ 2020-08-04 18:36  StelaYuri  阅读(285)  评论(0)    收藏  举报