HDU 6822 Paperfolding 2020杭电多校第五场(数学推导)

原题题面

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 L,R,U,D L,R,U,D.
1. L L L instruction means to fold it from left to right,
2. R R R instruction means to fold from right to left,
3. U U U instruction means to fold from top to bottom,
4. D D 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 n u m ( S ) num(S) num(S).
See the example and the picture for better understanding.
Now given a nonnegative integer n n n, the string S S S is generated from 4 n 4^n 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 ( n u m ( S ) ) m o d 998244353 E(num(S)) mod 998244353 E(num(S))mod998244353.
It can be shown that the answers can be represented by P Q \frac{P}{Q} QP, where P P P and Q Q Q are coprime integers, and print the value of P × Q − 1 m o d 998244353 P×Q^{−1} mod 998244353 P×Q1mod998244353.
在这里插入图片描述

输入格式

The first line contains a single integer T ( 1 ≤ T ≤ 1 0 5 ) T (1≤T≤10^5) T(1T105), the number of testcases.
Each of the next T lines contains a number n ( 0 ≤ n ≤ 1 0 18 ) n (0≤n≤10^{18}) n(0n1018).

题面分析

给一张无限大、不考虑厚度的纸,有四种操作。分别是向上、向下、向左、向右折,在完成 n n n次折叠后水平方向和竖直方向切开,问切开后纸片数量的期望。
易知向上向下等价、向左向右等价。故其实只有两种折法(以下称之为横折、竖折)
同时,也容易得到其实我也没法严谨证明折叠的顺序交换不影响答案(即横折2次竖折1次与竖折1次横折2次的结果相同)。
首先小范围打个表(指拿纸实际操作),可以发现以下规律:
【注:以下方法需要一定的数列知识,如果不会请看这里---->ACM数列相关
在给定了 A A A次横折与 B B B次竖折之后,记方案为 f ( A , B ) f(A,B) f(A,B),可以得到
f ( A , B ) = f ( B , A ) f(A,B)=f(B,A) f(A,B)=f(B,A)-------①
f ( A , B ) = 2 ∗ f ( A , B − 1 ) − ( 2 A + 1 ) f(A,B)=2*f(A,B-1)-(2^A+1) f(A,B)=2f(A,B1)(2A+1)-------②
f ( A , 0 ) = 2 ∗ f ( A − 1 , 0 ) − 2 f(A,0)=2*f(A-1,0)-2 f(A,0)=2f(A1,0)2-------③
f ( 0 , 0 ) = 4 f(0,0)=4 f(0,0)=4-------④
对③进行一阶线性递推,得 f ( A , 0 ) = 2 A + 2 f(A,0)=2^A+2 f(A,0)=2A+2
再对②进行一阶线性递推,得 f ( A , B ) = ( 2 A + 1 ) ( 2 B + 1 ) f(A,B)=(2^A+1)(2^B+1) f(A,B)=(2A+1)(2B+1)
接下来再统计折叠顺序交换后的种类
对于总折叠次数合计为 n n n时,即 A + B = n A+B=n A+B=n,可以得到答案为 A n n A A A A B B = n ! A ! B ! = n ! A ! ( n − A ) ! = C n A \frac{A_{n}^{n}}{A_{A}^{A}A_{B}^{B}}=\frac{n!}{A!B!}=\frac{n!}{A!(n-A)!}=C^A_{n} AAAABBAnn=A!B!n!=A!(nA)!n!=CnA
故答案 E E E
= 1 2 n ∑ i = 0 n ( 2 i + 1 ) ( 2 n − i + 1 ) C n i =\frac{1}{2^n}\sum_{i=0}^{n}(2^i+1)(2^{n-i}+1)C_{n}^i =2n1i=0n(2i+1)(2ni+1)Cni
= 1 2 n ∑ i = 0 n ( 2 n + 2 i + 2 n − i + 1 ) C n i =\frac{1}{2^n}\sum_{i=0}^{n}(2^n+2^i+2^{n-i}+1)C_{n}^i =2n1i=0n(2n+2i+2ni+1)Cni
= 1 2 n [ ∑ i = 0 n 2 n C n i + ∑ i = 0 n 2 i C n i + ∑ i = 0 n 2 n − i C n i + ∑ i = 0 n C n i ] =\frac{1}{2^n}[\sum_{i=0}^{n}2^nC_{n}^i+\sum_{i=0}^{n}2^iC_{n}^i+\sum_{i=0}^{n}2^{n-i}C_{n}^i+\sum_{i=0}^{n}C_{n}^i] =2n1[i=0n2nCni+i=0n2iCni+i=0n2niCni+i=0nCni]
记四个项为①、②、③、④
由二项式定理可知最后一项为 2 n 2^n 2n,同理①为 2 2 n 2^{2n} 22n
而对于③, ∑ i = 0 n 2 n − i C n i = ∑ i = 0 n 2 n − i C n n − i = ∑ i = 0 n 2 i C n i = \sum_{i=0}^{n}2^{n-i}C_{n}^i=\sum_{i=0}^{n}2^{n-i}C_{n}^{n-i}=\sum_{i=0}^{n}2^iC_{n}^i= i=0n2niCni=i=0n2niCnni=i=0n2iCni=②。
而对于②,注意到 ( 2 + 1 ) n = 3 n = ∑ i = 0 n 2 i C n i (2+1)^n=3^n=\sum_{i=0}^{n}2^{i}C_{n}^{i} (2+1)n=3n=i=0n2iCni
E = 2 2 n + 2 n + 2 ∗ 3 n 2 n E=\frac{2^{2n}+2^n+2*3^n}{2^n} E=2n22n+2n+23n
化简得
E = 2 n + 1 + 2 ∗ 3 2 n E=2^n+1+2*\frac{3}{2}^n E=2n+1+223n

AC代码(62ms)

#include <bits/stdc++.h>
using namespace std;
const long long mod=998244353;
inline long long quick_pow(long long a, long long b)//快速幂
{
    long long ans=1, base=a;
    while(b!=0)
    {
        if (b&1)
            ans=(long long) ans*base%mod;
        base=(long long) base*base%mod;
        b>>=1;
    }
    return ans;
}
void solve()
{
//    printf("%lld\n",33*quick_pow(2,mod-2)%mod);
    int t;
    scanf("%d", &t);
    while(t--)
    {
        long long n;
        scanf("%lld", &n);
        long long pow2n=quick_pow(2,n%(mod-1));
        long long pow3n=quick_pow(3,n%(mod-1));
        long long ans=(pow2n+1)%mod;
        ans=(ans+(long long)2*pow3n%mod*quick_pow(pow2n,mod-2)%mod)%mod;
        printf("%lld\n",ans);

    }
}
int main()
{
//    ios_base::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);
#ifdef ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    long long test_index_for_debug=1;
    char acm_local_for_debug;
    while(cin>>acm_local_for_debug)
    {
        cin.putback(acm_local_for_debug);
        if (test_index_for_debug>100)
        {
            throw runtime_error("Check the stdin!!!");
        }
        auto start_clock_for_debug=clock();
        solve();
        auto end_clock_for_debug=clock();
        cout<<"\nTest "<<test_index_for_debug<<" successful"<<endl;
        cerr<<"Test "<<test_index_for_debug++<<" Run Time: "
            <<double(end_clock_for_debug-start_clock_for_debug)/CLOCKS_PER_SEC<<"s"<<endl;
        cout<<"--------------------------------------------------"<<endl;
    }
#else
    solve();
#endif
    return 0;
}

后记

我一定是吃饱了撑的去算 f ( n , m ) f(n,m) f(n,m)
算这个破题还撕完我半本草稿纸…
DrGilbert 2020.8.4

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值