2020杭电多校第五场 Paperfolding(折纸,组合数学)

Problem Description
There is a piece of paper in rectangular shape with sufficient length and width (lay flat on the table). Execute an operation instruction according to a string of length n from left to right that only contains 4 different characters of L,R,U,D.

  1. L instruction means to fold it from left to right,

  2. R instruction means to fold from right to left,

  3. U instruction means to fold from top to bottom,

  4. D instruction means to fold in half from bottom to top.

Note that the operation is limited due to the limitation of the desktop. Namely, the fold operation is restricted. For example, if you fold the paper from left to right, you should let the left side overlap on the right side with no rotation.

Now, cut a knife horizontally (completely cut) at the center of the visible part of the paper, and then cut vertically (completely cut).

The number of pieces of the whole paper split is num(S).

See the example and the picture for better understanding.

Now given a nonnegative integer n, the string S is generated from 4n different possible outcomes in equal probability. Find the expected value of the number of pieces of the paper which is split, that is E(num(S)) mod 998244353.

It can be shown that the answers can be represented by PQ, where P and Q are coprime integers, and print the value of P×Q−1 mod 998244353.

Input
The first line contains a single integer T (1≤T≤105), the number of testcases.

Each of the next T lines contains a number n ( 0≤n≤1018 ).

Output
For each testcase, print the answer in one line.

Sample Input
2
0
1

Sample Output
4
6

题意:
折纸,折了m次以后横着一刀竖着一刀切,求最后分成多少块。

思路:
将折弯后的纸切的刀转到原来的纸上。
那么你往左(右)折x次,原来的纸竖着就会多切 2 x 2^x 2x刀。往上(下)折y次,原来的纸横着就会多切 2 y 2^y 2y刀。因为左右折(上下折)是等价的,所以可以把左右折当做竖着折,上下折当做横着折)

所以最后的块数是 ( x + 1 ) ∗ ( y + 1 ) (x+1)*(y+1) (x+1)(y+1)
我们只需要枚举最终纸横着切了多少刀,竖着切了多少刀即可。
所以结果是 ( n i ) ∗ ( 2 i + 1 ) ∗ ( 2 n − i + 1 ) \tbinom{n}{i}*(2^{i}+1)*(2^{n-i}+1) (in)(2i+1)(2ni+1)

展开再化简就可以得到
2 k ∗ ( 2 k + 1 ) + 3 k ∗ 2 {2^k*(2^k+1)+3^{k}*2} 2k(2k+1)+3k2

因为一共有 2 k 2^k 2k种可能(可以横着折也可以竖着折),所以最终结果是:
2 k ∗ ( 2 k + 1 ) + 3 k ∗ 2 2 k \frac{2^k*(2^k+1)+3^{k}*2}{2^{k}} 2k2k(2k+1)+3k2

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef long long ll;

const int mod = 998244353;
const int maxn = 1e5 + 7;

ll fac[maxn],inv[maxn];

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

ll C(ll n,ll m)
{
    if(m > n || m < 0)
        return 0;
    return fac[n] * ((inv[n - m] * inv[m]) % mod) % mod;
}

void init()
{
    fac[0] = 1;
    inv[0] = 1;
    for(int i = 1;i <= maxn - 2;i++)
    {
        fac[i] = (fac[i - 1] * i) % mod;
        inv[i] = qpow(fac[i],mod - 2);
    }
}


ll gcd(ll x,ll y) {
    return y == 0 ? x : gcd(y,x % y);
}

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

你可能感兴趣的:(#,其他比赛题目,#,组合数,#,概率)