题解 | #库洛牌小喵钓鱼#O(logn)的数学解

0-1翻转

https://ac.nowcoder.com/acm/contest/55515/A

链接不知道为啥给错了https://ac.nowcoder.com/acm/contest/55515/I
直接给出通项公式
P(n)=\frac{5(n^3+6n^2+11n)+54}{9(n^3+6n^2+11n)+54}
P(n)表示n张花色牌Tomoyo赢的概率,则
P(n)=\frac{1\cdot2n!}{n+2}P(n)+\frac{2\cdot2n!}{n+2}P(n-1)+...+\frac{n\cdot2n!}{n+2}P(1)+\frac{(n+1)\cdot2n!}{n+2}P(0)
也就是遍历下一轮夹在中间的数量的概率
即两张牌2!,另外n张牌n!种,中间夹着i张牌的种类数为n+1-i种
上面的式子可以进一步处理
\frac{n+2}{2n!}P(n)=P(n)+2P(n-1)+...+(n+1)P(0)
令S(n)为P(0~n)的求和
两边减去S(n)右边又可以用P(n-1)表示
\frac{n+2}{2n!}P(n)-S(n)=\frac{n+1!}{2(n-1)!}P(n-1)
将P(n)换成S(n)-S(n-1)可得
(n^2+3n)Sn+(n^2+n)S(n-2)=2(n+1)^2S(n-1)
求出Sn=\frac{10n(n(n+6)+11)+36}{18(n+2)(n+3)} (n>=2)
然后P(n)只要算S(n)-S(n-1)即可
t=int(input())
mod=998244353
import math
for i in range(t):
    n=int(input())
    if n==0:
        print(1)
        continue
    if n==1:
        print(0)
        continue
    a=10*n*(n*(n+6)+11)+36
    b=18*(n+2)*(n+3)
    
    c=10*(n-1)*((n-1)*(n+5)+11)+36
    d=18*(n+1)*(n+2)
    
    p=(a*d-b*c)
    q=b*d
    print(p*pow(q,mod-2,mod)%mod)
直接通项公式版
#include<iostream>
#include<algorithm>
using namespace std;
long long mod=998244353;
int main()
{
    int t;
    long long n,p,q,x;
    cin>>t;
    while(t--)
    {
        cin>>n;
        if(n==1)
        {
            cout<<0<<endl;
            continue;
        }
        p=(5*n*n*n+30*n*n+55*n+54)%mod;
        q=9*(n*n*n+6*n*n+11*n+6)%mod;
        x=mod-2;
        while(x)
        {
            if(x&1)
                p=p*q%mod;
            q=q*q%mod;
            x>>=1;
        }
        cout<<p<<endl;
    }
}


全部评论
巨佬,底下为什么是n+2不是(n+2)!呢,总的不是(n+2)!吗???
点赞
送花
回复
分享
发布于 2023-05-19 15:25 浙江

相关推荐

5 收藏 评论
分享
牛客网
牛客企业服务