E - Counting Sequences 2019年ICPC 上海网络赛 指数型生成函数

Counting Sequences

在这里插入图片描述

solution

序 列 [ a 1 , a 2 , a 3 . . . , a n ] , ( a i ∈ [ 1 , m ] ) , 问 序 列 中 a i 为 偶 数 的 个 数 非 奇 有 几 种 序列[a_1,a_2,a_3...,a_n],(a_i∈[1,m]),问序列中a_i为偶数的个数非奇有几种 [a1,a2,a3...,an],(ai[1,m])ai

考 虑 生 成 函 数 : 考虑生成函数:
T = ( 1 + x 2 2 ! + x 4 4 ! + x 6 6 ! + . . . ) m 2 ∗ ( 1 + x 1 ! + x 2 2 ! + x 3 3 ! + . . . ) m + 1 2 T=(1+\frac{x^2}{2!}+\frac{x^4}{4!}+\frac{x^6}{6!}+...)^\frac{m}{2}*(1+\frac{x}{1!}+\frac{x^2}{2!}+\frac{x^3}{3!}+...)^\frac{m+1}{2} T=(1+2!x2+4!x4+6!x6+...)2m(1+1!x+2!x2+3!x3+...)2m+1 [ l e t   m 2 = m + 1 2 f o r   t h e   t i m e   b e i n g ] [let~\frac{m}{2}=\frac{m+1}{2}for~the~time~being] [let 2m=2m+1for the time being]

由 于 偶 数 个 数 非 奇 , 只 能 出 现 0 , 2 , 4... , 即 第 一 项 , 由于偶数个数非奇,只能出现0,2,4...,即第一项, 024...,

而 奇 数 个 数 , 可 以 出 现 0 , 1 , 2 , 3 , 4... , 即 第 二 项 . 而奇数个数,可以出现0,1,2,3,4...,即第二项. 01234....

T = ( e x + e − x 2 ∗ e x ) m / 2 = ( e 2 x + 1 2 ) m / 2 = 1 2 m / 2 ( e 2 x + 1 ) m / 2 T=(\frac{e^{x}+e^{-x}}{2}*e^x)^{m/2}=(\frac{e^{2x}+1}{2})^{m/2}=\frac{1}{2^{m/2}}({e^{2x}+1})^{m/2} T=(2ex+exex)m/2=(2e2x+1)m/2=2m/21(e2x+1)m/2

二 项 式 展 开 : 二项式展开:

T = 1 2 m / 2 ∑ i = 0 m / 2 C m / 2 i e 2 i x T=\frac{1}{2^{m/2}}\sum\limits_{i=0}^{m/2}C_{m/2}^{i}e^{2ix} T=2m/21i=0m/2Cm/2ie2ix

幂 级 数 展 开 : 幂级数展开:

i f   m 2 = m + 1 2 : if~\frac{m}{2}=\frac{m+1}{2}: if 2m=2m+1:
T = 1 2 m / 2 ∑ i = 0 m / 2 C m / 2 i ∑ n = 0 ∞ ( 2 i ) n x n n ! T=\frac{1}{2^{m/2}}\sum\limits_{i=0}^{m/2}C_{m/2}^{i}\sum\limits_{n=0}^{∞}{(2i)}^n\frac{x^n}{n!} T=2m/21i=0m/2Cm/2in=0(2i)nn!xn

i f   m 2 + 1 = m + 1 2 : if~\frac{m}{2}+1=\frac{m+1}{2}: if 2m+1=2m+1:
T = 1 2 m / 2 ∑ i = 0 m / 2 C m / 2 i ∑ n = 0 ∞ ( 2 i + 1 ) n x n n ! T=\frac{1}{2^{m/2}}\sum\limits_{i=0}^{m/2}C_{m/2}^{i}\sum\limits_{n=0}^{∞}{(2i+1)}^n\frac{x^n}{n!} T=2m/21i=0m/2Cm/2in=0(2i+1)nn!xn

于 是 , 每 一 个 x n n ! 的 系 数 即 我 们 要 的 答 案 累 加 即 可 . 于是,每一个\frac{x^n}{n!}的系数即我们要的答案累加即可. n!xn.

code

/*SiberianSquirrel*//*CuteKiloFish*/
#include <bits/stdc++.h>
using namespace std;
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) (1ll * a * b / gcd(a, b))
#define Polynomial vector<int>
#define Inv(x) quick_pow(x, mod - 2)
#define DEBUG(x, y) cout << x << ": " << y << '\n';
using ld = long double;
using ll = long long;
using ull = unsigned long long;
//const ll mod = 998244353, mod_g = 3, img = 86583718;
const ll mod = 1000000007;
const ld pi = acos(-1.0);
template<typename T> inline T read() {
    T x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
template<typename T> inline T print(T x) {
    if(x < 0) { putchar('-'); x =- x; }
    if(x > 9) print(x / 10);
    putchar(x % 10 + '0');
}

ll fac[int(2e5 + 10)] = {1}, ifac[int(2e5 + 10)] = {1};

ll quick_pow(ll ans, ll p, ll res = 1) {
    for(; p; p >>= 1, ans = ans * ans % mod)
        if(p & 1) res = res * ans % mod;
    return res % mod;
}

ll C(ll n, ll m) {
    if(m == 0 || n == m) return 1;
    if(n < m) return 0;
    return 1ll * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

inline void solve() {
    for(int i = 1; i <= int(2e5); ++ i) fac[i] = fac[i - 1] * i % mod, ifac[i] = Inv(fac[i]);
    int o; cin >> o; while(o --) {
        ll n, m, res = 0; cin >> n >> m;
        for(int i = 0; i <= m / 2; ++ i) {
            res = (res + C(m / 2, i) * quick_pow(2 * i + (m & 1), n % (mod - 1)) % mod) % mod;
        }
        cout << Inv(quick_pow(2, m / 2)) * res % mod << '\n';
    }
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#ifdef ACM_LOCAL
    freopen("input", "r", stdin);
//    freopen("output", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << 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;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值