• Comet OJ


    题目描述

     

    Takuru 是一名能力者,他在地震时获得了念力致动的能力。所以他经常用自己的能力去干一些奇奇怪怪的事情。

    有一天他获得了一张 nn 个点的无向完全图,之后他使用了能力,导致这张图的 frac{n(n-1)}{2}2n(n1) 条边中的每一条都有 frac{x}{y}yx 的概率遭到破坏而消失。

    现在 Takuru 想知道这张无向图点集的全部 2^n2n 个的子集中,是独立集的子集数量的期望值。

    一张无向图 GG 的一个子集是独立集的定义如下:此点集 SS,满足对于任意的 x, y in Sx,yS,图 GG 中不存在连接 xx 和 yy 的边。(空集也是一个合法的独立集)

     
     

    输入描述

     

    一行三个整数 nn,xx 和 yy (1 leqslant n leqslant 10^51n105,1 leqslant x leqslant y < 9982443531xy<998244353)。

    输出描述

     

    输出一个整数,用如下方式计算:

    这张图独立集数量的期望可以写成一个最简分数 frac{X}{Y}​YX​,那么你需要输出一个整数 p​p​,满足 0leqslant p <998244353​0p<998244353​ 且 pY equiv X pmod {998244353}​pYX(mod998244353)​。保证合法的 p​p​ 存在且唯一。

    样例输入 1 

    3 1 2
    

    样例输出 1

    374341638
    
    Language: 
    C++
     
     思路:
    我们应该通过题意知道这样的性质:
    对于这n个节点的一个子集S,如果S含有m个节点,那么S是独立集的概率是 (x/y)的m*(m-1)/ 2 次方。
    因为m个节点的完全图有 m*(m-1)/ 2 条边,而且我们还可以知道,含有节点个数相同的子集,为独立集的概率相同。
     
    那么我们不妨枚举 子集的节点个数i,i从0到n,有 C(n,i)种节点个数为i的子集。为独立集的概率为 i*(i-1)/2
    我们只需要对于每一个 i 求个数*概率的sum和就是答案。
    注意取模运算中有除法的话,要转为乘以数值的关于mod的逆元(mod为质数就用费马小定理)。
    求C的话,我们预处理出1~n数的阶乘,然后每一次直接一个公式得到即可,虽然逆元过程有log,但是还是很快的。
    有更快的方法,可以预处理每一个数阶乘关于mod 的逆元。
     
    细节见代码:
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    inline void getInt(int* p);
    const int maxn=1000010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    ll fac[maxn];
    ll n,x,y;
    const ll mod=998244353ll;
    void init()
    {
        fac[0]=fac[1]=1ll;
        repd(i,2,maxn-1)
        {
            fac[i]=(fac[i-1]*i)%mod;
            // db(fac[i]);
        }
    }
    ll C(ll n,ll m)
    {
        ll res=fac[n];
        res*=powmod(fac[n-m],mod-2ll,mod);
        res%=mod;
        res*=powmod(fac[m],mod-2ll,mod);
        res%=mod;
        // db(res);
        return res;
    }
    int main()
    {
        //freopen("D:\common_text\code_stream\in.txt","r",stdin);
        //freopen("D:\common_text\code_stream\out.txt","w",stdout);
        init();
        gbtb;
        cin>>n>>x>>y;
        ll p = x*powmod(y,mod-2ll,mod);
        p%=mod;// 忘记加这一步,多了一个罚时
        ll ans=0ll;
        repd(i,0,n)
        {
            ans+=C(n,i)*powmod(p,1ll*i*(i-1ll)/2ll,mod)%mod;
            // cout<<C(n,i)<<" "<<powmod(p,1ll*i*(i-1ll)/2ll,mod)<<endl;
            ans%=mod;
        }
        cout<<ans<<endl;
        
        
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
     
     
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    第四章
    第三章
    第二章
    实验5-2: 编制程序,输入m、n(m≥n≥0)后,计算下列表达式的值并输出。 要求将计算阶乘的运算编写作函数fact(n),函数返回值的类型为float
    作业
    多人电费
    单人电费
    圆柱体积
    圆面积
    第七章
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10871741.html
Copyright © 2020-2023  润新知