• Codeforces 1279D


    Description

    思路

    做法一:组合数学

    操作分三步,前两步选孩子再选礼物,最后一步再选孩子。
    因此求出两步内选到礼物i的概率,再乘上想要礼物i的孩子的占比,求和所有礼物的结果就是答案。

    #include <bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    #define maxn 2000000
    #define M 998244353
    
    set<int> gi;
    ll sum[maxn];
    int cnt[maxn];
    
    
    ll qpow(ll a, ll b) {
        ll res = 1;
        while(b) {
            if(b & 1) res = res * a % M;
            a = (a * a) % M;
            b = b >> 1;
        }
        return res;
    }
    
    ll ddiv(ll a, ll b) { // a/b
        return a * qpow(b, M - 2) % M;
    }
    
     
    int main() {
        ios::sync_with_stdio(false);
        int n;
        cin >> n;
        ll tmp = ddiv(1, n);
        for(int i = 1; i <= n; i++) {
            int k;
            cin >> k;
            ll ttmp = ddiv(1, k);
            for(int i = 0; i < k; i++) {
                int g;
                cin >> g;
                gi.insert(g);
                sum[g] = (sum[g] + (tmp * ttmp % M)) % M;
                cnt[g]++;
            }
        }
        ll ans = 0;
        for(auto g : gi) {
            ans = (ans + (sum[g] * ddiv(cnt[g], n)) % M) % M;
        }
        cout << ans ;
    }
    

    做法二:dp
    dp[i]代表选了第i个孩子的概率。然后有四种情况分类讨论,详情见代码。
    注意,对于这个解法,用了太多次的快速幂会超时,因此要保存一些快速幂的结果减少计算量。
    显然,做法一更好

    
    #include <bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    #define maxn 2000000
    #define M 998244353
     
    ll dp[maxn];
    vector<int> ch[maxn];
    vector<int> gi[maxn];
    ll sum[maxn];
     
     
    ll qpow(ll a, ll b) {
        ll res = 1;
        while(b) {
            if(b & 1) res = res * a % M;
            a = (a * a) % M;
            b = b >> 1;
        }
        return res;
    }
     
    ll ddiv(ll a, ll b) { // a/b
        return a * qpow(b, M - 2) % M;
    }
     
    inline ll pow2(ll a) {
        return (a * a) % M;
    }
     
    int main() {
        ios::sync_with_stdio(false);
        int n;
        cin >> n;
        for(int i = 1; i <= n; i++) {
            int k;
            cin >> k;
            while(k--) {
                int g;
                cin >> g;
                ch[i].push_back(g);
            }
        }
        dp[0] = 1;
        for(int i = 1; i <= n; i++) {
            ll a = pow2(ddiv(i - 1, i)) * dp[i - 1] % M ;
            ll b = pow2(ddiv(1, i));
            ll c = 0;
            ll d = 0;
            for(int g : ch[i]) {
                c = (c + ddiv(1, ch[i].size()) * ddiv(gi[g].size(), i - 1) % M) % M;
                d = (d + (ddiv(1, i - 1) * sum[g]) % M) % M;
            }
            for(int g : ch[i]) {
                gi[g].push_back(i);
                if(sum[g] == 0) sum[g] = ddiv(1, ch[i].size());
                else sum[g] = (sum[g] + ddiv(1, ch[i].size())) % M;
            }
            ll tmp =  (ddiv(1, i) * ddiv(i - 1, i) % M);
            d = tmp * d % M;
            c = tmp * c % M;
            dp[i] = (a + b + c + d) % M;
        }
        cout << dp[n];
    }
    
  • 相关阅读:
    谈谈jQuery之绑定事件
    手机移动端WEB资源整合
    2016移动端web5分钟速成(适合新手)
    日常整理的一些网址
    web服务器页面错误代码集
    jQuery事件绑定的最佳实践
    前端体系
    js刷新页面的几种方法
    JAVA的静态变量、静态方法、静态类
    在Hadoop集群中添加机器和删除机器
  • 原文地址:https://www.cnblogs.com/limil/p/12697089.html
Copyright © 2020-2023  润新知