题解 msc的背包

传送门


【分析】

不难写出,生成函数 \(\displaystyle F(x)=({1\over 1-x})^n\cdot ({1\over 1-x^2})^m={(1+x)^n\over (1-x^2)^{n+m}}\)

\(\displaystyle F[k]=\sum_{i+j=k} [2\mid j]\dbinom{n}{i}\dbinom{-(n+m)}{j\over 2}=\sum_{i=0}^n[2\mid k-i]\dbinom{n}{i} \dbinom{n+m-1+{k-i\over 2}}{n+m-1}\)

考虑 \(\displaystyle \dbinom n i={(n-i)\cdot (n-i+1)\over (i+1)\cdot (i+2)}\dbinom n {i-2}\)

\(\displaystyle \dbinom{n+m-1+j}{n+m-1}={(n+m-1+j)^{\underline{n+m-1}}\over (n+m-1)!}=\dbinom {n+m-1+j}{j}={n+m+j-1\over j}\cdot \dbinom{n+m-1+(j-i)}{j-1}\)

\(res_1=\dbinom{n}{k\bmod 2}, res_2=\dbinom{n+m+(k/2)-1}{n+m-1}\)

而后 \(F[k]+=res_1\cdot res_2\)

新的由 \(\displaystyle res_1={(n-i)\cdot (n-i-1)\over i\cdot (i+1)}\cdot res_1, res_2={j\over n+m+j-1}\cdot res_2\)\(O(\log n)\) 生成

需要考虑快速幂的复杂度

总复杂度转为遍历复杂度,即 \(O(n\log n)\)


【代码】

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef double db;
#define fi first
#define se second
#define int ll
const int MOD=998244353;
ll n, m, k;
inline ll fpow(ll a,ll x) { ll ans=1; for(;x;x>>=1,a=a*a%MOD) if(x&1) ans=ans*a%MOD; return ans; }
inline ll ans(){
    ll res1, res2;
    res1=1, res2=1;
    for(int i=1, j=n+m+(k>>1)-1, I=n+m-1; i<=I; ++i, --j)
        res1=res1*j%MOD, res2=res2*i%MOD;
    res2=res1*fpow(res2, MOD-2)%MOD;
    res1=((k&1)?n:1);

    ll res=0;
    for(int i=k&1, j=k>>1;i<=n&&j>=0;i+=2, --j){
        res = (res+res1*res2)%MOD;
        res1 = res1*(n-i)%MOD*(n-i-1)%MOD*fpow( (i+2)*(i+1)%MOD, MOD-2 )%MOD;
        res2 = res2*j%MOD*fpow(n+m+j-1, MOD-2)%MOD;
    }
    return res;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin>>n>>m>>k;
    cout<<ans();
    cout.flush();
    return 0;
}
posted @ 2021-07-16 20:05  JustinRochester  阅读(33)  评论(0编辑  收藏  举报