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
AC × 3
AC × 20
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