【09.07】CCPC网络赛05题 Easy Math Problem(矩阵+NTT/递推)

传送门

题解

不想写了

代码(ntt)

/*************************************************************************
    > File Name: 2.cpp
    > Author: Knowledge-Pig
    > Mail: 925538513@qq.com
    > Blog: https://www.cnblogs.com/Knowledge-Pig/
    > Created Time: 2021年09月03日 星期五 17时27分00秒
************************************************************************/

#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define LL long long
#define pb push_back
#define fi first
#define se second
#define pr pair<int,int>
#define mk(a,b) make_pair(a,b)
#define endl '\n'
using namespace std;
const int mod = 998244353, maxx = 2e5 + 10;
LL qpow(LL x, LL y){
    LL res = 1;
    while(y){
        if(y & 1) res = res * x % mod;
        x = x * x % mod;
        y >>= 1;
    }
    return res;
}
struct Matrix{
    LL a[2][2];
    Matrix(){ memset(a, 0, sizeof(a)); }
    void clear(){ memset(a, 0, sizeof(a)); }
    Matrix operator + (const Matrix &A) const{
        Matrix tmp;
        For(i, 0, 1) For(j, 0, 1)
            tmp.a[i][j] = (a[i][j] + A.a[i][j]) % mod;
        return tmp;
    }

    Matrix operator - (const Matrix &A) const{
        Matrix tmp;
        For(i, 0, 1) For(j, 0, 1)
            tmp.a[i][j] = (a[i][j] - A.a[i][j] + mod) % mod;
        return tmp;
    }

    Matrix operator * (const Matrix &A) const{
        Matrix tmp;
        For(i, 0, 1) For(j, 0, 1) For(k, 0, 1)
            tmp.a[i][j] = (tmp.a[i][j] + a[i][k] * A.a[k][j] % mod) % mod;
        return tmp;
    }

    Matrix operator * (const LL c) const{
        Matrix tmp;
        For(i, 0, 1) For(j, 0, 1)
            tmp.a[i][j] = a[i][j] * c % mod;
        return tmp;
    }
    
    void print(){
        For(i, 0, 1) For(j, 0, 1) cout << a[i][j] << (j ? '\n' : ' ');
    }
}A[maxx], B[maxx];

LL fac[maxx], inv[maxx];
int m, dp[maxx];

void putin(Matrix &tmp, int x, int y){
    tmp.a[0][0] = x; tmp.a[0][1] = y;
    tmp.a[1][0] = 1; tmp.a[1][1] = 0;
}

void ntt(Matrix *x, bool idft){
    for(int i = 1; i < m; ++i) if(i < dp[i]) swap(x[i], x[dp[i]]);
    for(int i = 2; i <= m; i <<= 1){
        LL w = qpow(3, (mod - 1) / i);
        int len = i >> 1;
        if(idft) w = qpow(w, mod - 2);
        for(int k = 0; k < m; k += i){
            LL p = 1;
            for(int l = k; l < k + len; ++l){
                Matrix tmp = x[len + l] * p;
                x[len + l] = x[l] - tmp;
                x[l] = x[l] + tmp;
                p = p * w % mod;
            }
        }
    }
}
int main(){
    ios::sync_with_stdio(false); cin.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.in", "r", stdin);
    freopen("output.out", "w", stdout);
#endif
    fac[0] = 1;
    for(int i = 1; i <= 200000; ++i) fac[i] = fac[i - 1] * i % mod;
    inv[200000] = qpow(fac[200000], mod - 2);
    for(int i = 199999; i >= 0; --i) inv[i] = inv[i + 1] * (i + 1) % mod;
    int T;
    cin >> T;
    while(T--){
        int n, a, b, c, d, e;
        cin >> n >> a >> b >> c >> d >> e;
        A[0].clear(); B[0].clear();
        putin(A[1], b, c); putin(B[1], d, e);
        for(int i = 2; i <= n; ++i){
            A[i] = A[i - 1] * A[1];
            B[i] = B[i - 1] * B[1];
        }    
        for(int i = 2; i <= n; ++i){
            A[i] = A[i] * inv[i];
            B[i] = B[i] * inv[i];
        }
        for(m = 1; m <= n * 2; m <<= 1);
        for(int i = n + 1; i < m; ++i) A[i].clear(), B[i].clear();
        for(int i = 1; i < m; ++i){
            dp[i] = (dp[i >> 1] >> 1) | ((i & 1)? m >> 1 : 0);
        }
        ntt(A, 0); ntt(B, 0);
        for(int i = 0; i < m; ++i) A[i] = B[i] * A[i];
        ntt(A, 1);

        Matrix sum, ans; ans.a[1][0] = qpow(c, mod - 2) * a % mod;
        for(int i = 2; i <= n * 2; ++i) sum = sum + A[i] * fac[i];
        ans = sum * qpow(m, mod - 2) * ans;
        cout << (ans.a[0][0] + mod) % mod << endl;
    }
    return 0;
}

代码(递推)

/*************************************************************************
    > File Name: 2.cpp
    > Author: Knowledge-Pig
    > Mail: 925538513@qq.com
    > Blog: https://www.cnblogs.com/Knowledge-Pig/
    > Created Time: 2021年09月03日 星期五 17时27分00秒
************************************************************************/

#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define LL long long
#define pb push_back
#define fi first
#define se second
#define pr pair<int,int>
#define mk(a,b) make_pair(a,b)
#define endl '\n'
using namespace std;
const int mod = 998244353, maxx = 2e5;
LL qpow(LL x, LL y){
    LL res = 1;
    while(y){
        if(y & 1) res = res * x % mod;
        x = x * x % mod;
        y >>= 1;
    }
    return res;
}
struct Matrix{
    LL a[2][2];
    Matrix(){ memset(a, 0, sizeof(a)); }
    void clear(){ memset(a, 0, sizeof(a)); }
    Matrix operator + (const Matrix &A) const{
        Matrix tmp;
        For(i, 0, 1) For(j, 0, 1)
            tmp.a[i][j] = (a[i][j] + A.a[i][j]) % mod;
        return tmp;
    }

    Matrix operator - (const Matrix &A) const{
        Matrix tmp;
        For(i, 0, 1) For(j, 0, 1)
            tmp.a[i][j] = (a[i][j] - A.a[i][j] + mod) % mod;
        return tmp;
    }

    Matrix operator * (const Matrix &A) const{
        Matrix tmp;
        For(i, 0, 1) For(j, 0, 1) For(k, 0, 1)
            tmp.a[i][j] = (tmp.a[i][j] + a[i][k] * A.a[k][j] % mod) % mod;
        return tmp;
    }

    Matrix operator * (const LL c) const{
        Matrix tmp;
        For(i, 0, 1) For(j, 0, 1)
            tmp.a[i][j] = a[i][j] * c % mod;
        return tmp;
    }
    
    void print(){
        For(i, 0, 1) For(j, 0, 1) cout << a[i][j] << (j ? '\n' : ' ');
    }
}A[maxx + 10], B[maxx + 10], f[maxx + 10], I;

LL fac[maxx + 10], inv[maxx + 10];

void putin(Matrix &tmp, int x, int y){
    tmp.a[0][0] = x; tmp.a[0][1] = y;
    tmp.a[1][0] = 1; tmp.a[1][1] = 0;
}

LL C(int n, int m){
    return  fac[n] * inv[m] % mod * inv[n - m] % mod;
}
int main(){
    ios::sync_with_stdio(false); cin.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.in", "r", stdin);
    freopen("output.out", "w", stdout);
#endif
    fac[0] = I.a[0][0] = I.a[1][1] = 1;
    for(int i = 1; i <= maxx; ++i) fac[i] = fac[i - 1] * i % mod;
    inv[maxx] = qpow(fac[maxx], mod - 2);
    for(int i = maxx - 1; i >= 0; --i) inv[i] = inv[i + 1] * (i + 1) % mod;
    int T;
    cin >> T;
    while(T--){
        int n, a, b, c, d, e;
        cin >> n >> a >> b >> c >> d >> e;
        putin(B[1], b, c); putin(A[1], d, e);
        f[n].clear();
        for(int j = 1; j <= n; ++j){
            f[n] = f[n] + B[j] * C(n + j, n);
            B[j + 1] = B[j] * B[1];
            A[j + 1] = A[j] * A[1];
        }

        A[0] = I - B[1];

        for(int i = n - 1; i >= 1; --i)
            f[i] = f[i + 1] * A[0] + B[n + 1] * C(i + 1 + n, n) - B[1];

        Matrix sum, ans; ans.a[1][0] = qpow(c, mod - 2) * a % mod;

        for(int i = 1; i <= n; ++i) sum = sum + A[i] * f[i];
        ans = sum * ans;
        cout << (ans.a[0][0] + mod) % mod << endl;
    }
    return 0;
}
posted @ 2021-09-07 11:08  Knowledge-Pig  阅读(24)  评论(0)    收藏  举报