Submission #70982916
Source Code Expand
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e5 + 10, P = 998244353;
const int g = 3;
const int inv_g = 332748118;
int n, m, a[N], b[N];
int fpm(int a, int b = P - 2, int p = P) {
int res = 1;
while (b) {
if (b & 1) res = 1ll * res * a % p;
b >>= 1, a = 1ll * a * a % p;
}
return res;
}
int fac[N], inv[N];
void init(int n = N - 1) {
fac[0] = 1;
for (int i = 1; i <= n; ++ i ) fac[i] = 1ll * fac[i - 1] * i % P;
inv[n] = fpm(fac[n]);
for (int i = n - 1; ~i; -- i ) inv[i] = 1ll * inv[i + 1] * (i + 1) % P;
}
void ntt(vector<int>& a, int type) {
int n = a.size();
vector<int> rev(n);
for (int i = 0; i < n; ++ i ) {
rev[i] = rev[i >> 1] >> 1;
if (i & 1) rev[i] |= n >> 1;
}
for (int i = 0; i < n; ++ i ) {
if (i < rev[i]) swap(a[i], a[rev[i]]);
}
for (int mid = 1; mid < n; mid <<= 1) {
long long w_m = fpm(type == 1 ? g : inv_g, (P - 1) / (mid * 2)); // 单位根
for (int j = 0; j < n; j += mid * 2) {
long long w = 1;
for (int k = 0; k < mid; ++k) {
long long u = a[j + k];
long long v = w * a[j + k + mid] % P;
a[j + k] = (u + v) % P;
a[j + k + mid] = (u - v + P) % P;
w = w * w_m % P;
}
}
}
// 逆变换需乘以n的逆元(模P)
if (type == -1) {
long long inv_n = fpm(n, P - 2);
for (int i = 0; i < n; ++ i ) {
a[i] = a[i] * inv_n % P;
}
}
}
vector<int> multi(vector<int> A, vector<int> B) {
int n = A.size(), m = B.size();
if (n == 0 || m == 0) return {};
int res_len = n + m - 1;
int lim = 1;
while (lim < res_len) lim <<= 1;
A.resize(lim, 0);
B.resize(lim, 0);
for (int& x : A) x = (x % P + P) % P;
for (int& x : B) x = (x % P + P) % P;
ntt(A, 1);
ntt(B, 1);
vector<int> C(lim);
for (int i = 0; i < lim; ++ i ) {
C[i] = 1LL * A[i] * B[i] % P;
}
ntt(C, -1);
C.resize(res_len);
return C;
}
signed main() {
init();
cin >> n >> m;
for (int i = 1; i <= n; ++ i ) cin >> a[i];
for (int i = 1; i <= m; ++ i ) cin >> b[i];
vector<int> A(N), B(N);
for (int i = 1; i <= n; ++ i ) (A[a[i]] += fac[a[i]]) %= P;
for (int i = 1; i <= m; ++ i ) (B[N - 1 - b[i]] += inv[b[i]]) %= P;
vector<int> C = multi(A, B);
int res = 0;
for (int i = 0; i <= 5e5; ++ i ) {
res += 1ll * inv[i] * C[i + N - 1] % P;
res %= P;
// if (C[i + N - 1]) {
// cout <<
// }
}
cout << res;
return 0;
}
Submission Info
| Submission Time | |
|---|---|
| Task | G - Sum of Binom(A, B) |
| User | huk2 |
| Language | C++23 (GCC 15.2.0) |
| Score | 575 |
| Code Size | 2508 Byte |
| Status | AC |
| Exec Time | 375 ms |
| Memory | 59632 KiB |
Judge Result
| Set Name | Sample | All | ||||
|---|---|---|---|---|---|---|
| Score / Max Score | 0 / 0 | 575 / 575 | ||||
| Status |
|
|
| Set Name | Test Cases |
|---|---|
| Sample | 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt |
| All | 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_random_00.txt, 01_random_01.txt, 01_random_02.txt, 01_random_03.txt, 01_random_04.txt, 01_random_05.txt, 01_random_06.txt, 01_random_07.txt, 01_random_08.txt, 01_random_09.txt, 02_handmade_00.txt, 02_handmade_01.txt, 02_handmade_02.txt, 02_handmade_03.txt, 02_handmade_04.txt, 02_handmade_05.txt, 02_handmade_06.txt |
| Case Name | Status | Exec Time | Memory |
|---|---|---|---|
| 00_sample_00.txt | AC | 189 ms | 51788 KiB |
| 00_sample_01.txt | AC | 189 ms | 51780 KiB |
| 00_sample_02.txt | AC | 186 ms | 51664 KiB |
| 01_random_00.txt | AC | 297 ms | 56480 KiB |
| 01_random_01.txt | AC | 253 ms | 54496 KiB |
| 01_random_02.txt | AC | 311 ms | 57192 KiB |
| 01_random_03.txt | AC | 323 ms | 57496 KiB |
| 01_random_04.txt | AC | 371 ms | 59440 KiB |
| 01_random_05.txt | AC | 375 ms | 59568 KiB |
| 01_random_06.txt | AC | 371 ms | 59628 KiB |
| 01_random_07.txt | AC | 371 ms | 59580 KiB |
| 01_random_08.txt | AC | 368 ms | 59628 KiB |
| 01_random_09.txt | AC | 368 ms | 59632 KiB |
| 02_handmade_00.txt | AC | 186 ms | 51824 KiB |
| 02_handmade_01.txt | AC | 370 ms | 59584 KiB |
| 02_handmade_02.txt | AC | 189 ms | 51776 KiB |
| 02_handmade_03.txt | AC | 230 ms | 55696 KiB |
| 02_handmade_04.txt | AC | 278 ms | 55672 KiB |
| 02_handmade_05.txt | AC | 322 ms | 59588 KiB |
| 02_handmade_06.txt | AC | 370 ms | 59520 KiB |