【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;
}

浙公网安备 33010602011771号