QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#129765 | #4547. Connectivity of Erdős–Rényi Graph | batrr# | AC ✓ | 1110ms | 14612kb | C++17 | 5.2kb | 2023-07-22 23:24:50 | 2023-07-22 23:24:51 |
Judging History
answer
#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
const int N = 300500, inf = 1e9, mod = 998244353;
const ll INF = 1e18;
mt19937 rnd(228);
const int root = 646;
const int root_1 = 208611436;
const int root_pw = 1 << 20;
int mult(int a, int b) {
return (1LL * a * b) % mod;
}
int pw(int a, ll b) {
if (b == 0) return 1;
if (b & 1) return mult(a, pw(a, b - 1));
int res = pw(a, b / 2);
return mult(res, res);
}
int sub(int a, int b) {
int s = a - b;
if (s < 0) s += mod;
return s;
}
int sum(int a, int b) {
int s = a + b;
if (s >= mod) s -= mod;
return s;
}
void fft(vector<int> &a, bool invert) {
int n = (int) a.size();
for (int i = 1, j = 0; i < n; ++i) {
int bit = n >> 1;
for (; j >= bit; bit >>= 1)
j -= bit;
j += bit;
if (i < j)
swap(a[i], a[j]);
}
for (int len = 2; len <= n; len <<= 1) {
int wlen = invert ? root_1 : root;
for (int i = len; i < root_pw; i <<= 1)
wlen = int(wlen * 1ll * wlen % mod);
for (int i = 0; i < n; i += len) {
int w = 1;
for (int j = 0; j < len / 2; ++j) {
int u = a[i + j], v = int(a[i + j + len / 2] * 1ll * w % mod);
a[i + j] = u + v < mod ? u + v : u + v - mod;
a[i + j + len / 2] = u - v >= 0 ? u - v : u - v + mod;
w = int(w * 1ll * wlen % mod);
}
}
}
if (invert) {
int nrev = pw(n, mod - 2);
for (int i = 0; i < n; ++i)
a[i] = int(a[i] * 1ll * nrev % mod);
}
}
void poly_mult(vector<int> &a, vector<int> b) {
if (min(a.size(), b.size()) < 128) {
vector<int> c = a;
a.assign(a.size() + b.size() - 1, 0);
for (int i = 0; i < c.size(); ++i) {
for (int j = 0; j < b.size(); ++j) {
a[i + j] = sum(a[i + j], mult(c[i], b[j]));
}
}
return;
}
int s = a.size() + b.size();
int r = 1;
while (r < s) r *= 2;
a.resize(r);
b.resize(r);
fft(a, false);
fft(b, false);
for (int j = 0; j < r; j++) {
a[j] = mult(a[j], b[j]);
}
fft(a, true);
}
vector<int> inversePoly(vector<int> a) {
int n = a.size(), m = (n + 1) >> 1;
if (n == 1) {
return vector<int>(1, pw(a[0], mod -2));
} else {
vector<int> b = inversePoly(vector<int>(a.begin(), a.begin() + m));
int need = n << 1, nbase = 0;
while (1 << nbase < need) {
++nbase;
}
int sz = 1 << nbase;
assert(a.size() + 2 * b.size() <= sz);
a.resize(sz);
b.resize(sz);
fft(a, false);
fft(b, false);
for (int i = 0; i < sz; ++i) {
a[i] = mult(sub(2, mult(a[i], b[i])), b[i]);
}
fft(a, true);
a.resize(n);
return a;
}
}
int qq, a, b;
const int maxN = 5e5 + 10;
int fact[maxN], invfact[maxN], inv[maxN];
ll C2[maxN];
void solve() {
cin >> qq >> a >> b;
int p = mult(a, pw(b, mod - 2));
p = sub(1, p);
vector<int> T(qq);
for (int i = 0; i < qq; i++) {
cin >> T[i];
}
int N = *max_element(T.begin(), T.end());
vector<int> C(N);
vector<int> rev(N);
if (a == b) {
for (int t = 0; t < qq; t++) cout << 1 << " ";
cout << '\n';
return;
}
int inv_p = pw(p, mod - 2);
for (int k = 1; k <= N; k++) {
rev[k - 1] = mult(invfact[k - 1], pw(inv_p, C2[k]));
}
for (int d = 0; d < N; d++) {
C[d] = mult(invfact[d], pw(inv_p, C2[d]));
}
C = inversePoly(C);
poly_mult(rev, C);
vector<int> F(N + 1);
rev.resize(N);
for (int i = 1; i <= N; i++) {
F[i] = mult(rev[i - 1], mult(fact[i - 1], pw(p, C2[i])));
// cout << F[i] << " " << i << " " << sub(1, p) << endl;
}
vector<int> ANS(N + 1);
// for (int i = 1; i <= N )
for (int i = 1; i <= N; i++) {
F[i] = mult(F[i], mult(invfact[i], pw(inv_p, C2[i])));
}
vector<int> S(N + 1);
for (int i = 0; i <= N; i++) {
S[i] = mult(invfact[i], pw(inv_p, C2[i]));
}
poly_mult(F, S);
F.resize(N + 1);
for (int t = 0; t < qq; t++) {
cout << mult(F[T[t]], mult(fact[T[t]], pw(p, C2[T[t]]))) << " ";
}
cout << '\n';
}
int main() {
#ifdef DEBUG
freopen("input.txt", "r", stdin);
#endif
ios_base::sync_with_stdio(false);
for (int i = 0; i < maxN; i++) {
C2[i] = (1LL * i * (i - 1)) / 2;
}
fact[0] = invfact[0] = fact[1] = invfact[1] = inv[1] = 1;
for (int i = 2; i < maxN; i++) {
fact[i] = mult(fact[i - 1], i);
inv[i] = mult(inv[mod % i], sub(0, mod / i));
invfact[i] = mult(invfact[i - 1], inv[i]);
}
int t = 100000;
cin >> t;
for (int i = 1; i <= t; i++) {
// cout << "Case #" << i << endl;
solve();
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1110ms
memory: 14612kb
input:
100 395 155621128 377317019 369 287 1149 1448 1773 2531 655 947 1904 2436 450 1768 1111 774 1902 2353 1593 1628 1816 1791 1319 1489 502 930 837 106 2282 1817 1790 484 815 1037 2401 1112 1132 927 1937 827 2459 514 1530 304 437 685 1499 1524 506 1865 346 1473 1526 2329 2313 322 2251 862 2398 482 1134 ...
output:
260432516 334882823 885846335 260925036 748753600 391528419 900699180 781237678 531700127 836307276 173630117 683289419 568240381 182639244 727159998 52292561 191462705 421376235 703731130 918685918 919686426 340384164 924254848 206299675 737847232 853361852 612936763 402860906 977324131 506544530 3...
result:
ok 100 lines