zoukankan      html  css  js  c++  java
  • CF932E Team Work

    CF932E Team Work

    讲道理不难,但是我推不出来(指在模数为998244353的情况下的 (O(k)) 做法)我只能搞出 (O (K log N)) 的,但是需要模数为998244353(你要用FFT也行,不保证精度)。

    那么考虑 (O(K^2))。显然,你只需要 这题 就行了。 (推导过程容易发现 (j gt k)(j=0) 时,值为0。

    [sum_{i=1}^n inom n i i^k \ = sum_{i=1}^n inom n i sum_{j=0}^i {krace j}j! inom i j \ = sum_{j=1}^k {k race j} j! sum_{i=j}^n inom n i inom i j\ = sum_{j=1}^k {k race j} j! sum_{i=j}^n inom n j inom {n-j} {i-j} \ = sum_{j=1}^k {k race j} j! inom n j sum_{i=j}^n inom {n-j} {i-j} \ = sum_{j=1}^k {k race j} j! inom n j 2^{n-j} ]

    这题就可以 (O(K^2)) 完成了。但是我们怎么可以放弃(大雾),我们已知

    [{n race k}\ = frac{1}{k!} sum_{i=0}^k (-1)^i inom ki (k-i)^n \ = sum_{i=0}^k frac{(-1)^i}{i!} frac {(k-i)^n} {(k-i)!} ]

    那么我们可以直接卷一下就变成 (O (K log N)) 了(模数998244353)。

    (O(K)) 做法请去看min_25博客

    /*
        Name:
        Author: Gensokyo_Alice
        Date:
        Description:
    */
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <vector>
    #include <ctime>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    
    using namespace std;
    
    typedef long long ll;
    const ll MAXN = (1LL << 20) + 10, MOD = 1e9+7, INF = 0x3f3f3f3f3f3f3f3f;
    
    ll N, K, ans, fac[MAXN], inv[MAXN];
    
    ll ks(ll, ll); 
    
    namespace subtask2 {
        ll str[MAXN];
        void work() {
            str[1] = 1;
            for (ll i = 2; i <= K; i++)
                for (ll j = i; j >= 1; j--)
                    str[j] = (str[j-1] + (j * str[j] % MOD)) % MOD;
            ll now = 1;
            for (ll j = 1; j <= K; j++) {
                ll invnow = inv[j] * fac[j-1] % MOD;
                now = now * (N-j+1) % MOD * invnow % MOD;
                (ans += str[j] * fac[j] % MOD * now % MOD * ks(2, N-j) % MOD) %= MOD;
            }
            printf("%lld
    ", ans);
        }
    }
    
    int main() {
        scanf("%lld%lld", &N, &K); inv[0] = inv[1] = fac[1] = fac[0] = 1;
        for (ll i = 2; i <= K; i++) fac[i] = fac[i-1] * i % MOD, inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
        for (ll i = 1; i <= K; i++) inv[i] = inv[i-1] * inv[i] % MOD;
        if (K <= 5000) {
            subtask2::work();
            return 0;
        }
        return 0;
    }
    
    ll ks(ll n, ll tim) {
    	bool flag = 0;
    	if (tim < 0) tim = -tim, flag = 1;
        ll ret = 1;
        while (tim) {
            if (tim & 1) ret = ret * n % MOD;
            n = n * n % MOD;
            tim >>= 1;
        }
        if (flag) return ks(ret, MOD - 2);
        return ret;
    }
    
  • 相关阅读:
    [deviceone开发]-底部弹出选择
    [deviceone开发]-动态添加组件add方法的示例
    [deviceone开发]-openPage的动画效果示例
    [deviceone开发]-do_Album的简单示例
    [deviceone开发]-Star分享的几个示例
    [deviceone开发]-do_Webview的基本示例
    [deviceone开发]-do_Webview加载JQueryMobile的示例
    [deviceone开发]-心形点赞动画示例
    函数式编程思维学习 (1)
    android 14.04 64位 adb cannot run program adb
  • 原文地址:https://www.cnblogs.com/Gensokyo-Alice/p/14204631.html
Copyright © 2011-2022 走看看