QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#316552 | #8180. Bridge Elimination | ucup-team2112# | TL | 1988ms | 6496kb | C++20 | 9.7kb | 2024-01-27 21:45:18 | 2024-01-27 21:45:18 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
using ll = long long;
int norm(int x) {
if (x < 0) {
x += mod;
}
if (x >= mod) {
x -= mod;
}
return x;
}
template<class T>
T power(T a, int b) {
T res = 1;
for (; b; b /= 2, a *= a) {
if (b % 2) {
res *= a;
}
}
return res;
}
struct mint {
int x;
mint(int x = 0) : x(norm(x)) {}
int val() const {
return x;
}
mint operator-() const {
return mint(norm(mod - x));
}
mint inv() const {
assert(x != 0);
return power(*this, mod - 2);
}
mint &operator*=(const mint &rhs) {
x = ll(x) * rhs.x % mod;
return *this;
}
mint &operator+=(const mint &rhs) {
x = norm(x + rhs.x);
return *this;
}
mint &operator-=(const mint &rhs) {
x = norm(x - rhs.x);
return *this;
}
mint &operator/=(const mint &rhs) {
return *this *= rhs.inv();
}
friend mint operator*(const mint &lhs, const mint &rhs) {
mint res = lhs;
res *= rhs;
return res;
}
friend mint operator+(const mint &lhs, const mint &rhs) {
mint res = lhs;
res += rhs;
return res;
}
friend mint operator-(const mint &lhs, const mint &rhs) {
mint res = lhs;
res -= rhs;
return res;
}
friend mint operator/(const mint &lhs, const mint &rhs) {
mint res = lhs;
res /= rhs;
return res;
}
friend std::istream &operator>>(std::istream &is, mint &a) {
ll v;
is >> v;
a = mint(v);
return is;
}
friend std::ostream &operator<<(std::ostream &os, const mint &a) {
return os << a.val();
}
};
const int maxn = 405;
mint f[maxn][maxn];
mint ff[maxn];
mint g[maxn];
mint new_g[maxn];
mint choose[maxn][maxn];
mint dp[405][405];
mint new_dp[405][405];
const int MAXN = 2048 + 5;
const int MOD = 998244353;
using LL = long long;
#define Gi 3
#define Int register int
#define mod 998244353
#define Gii 332748118
struct GO{
inline int quick_pow (int a,int b)
{
int res = 1;
for (; b; b >>= 1,a = 1ll * a * a % mod) if (b & 1) res = 1ll * res * a % mod;
return res;
}
int limit,l,r[MAXN];
inline void NTT (int *a,int type)
{
for (Int i = 0; i < limit; ++ i) if (i < r[i]) swap (a[i],a[r[i]]);
for (Int mid = 1; mid < limit; mid <<= 1)
{
int Wn = quick_pow (type == 1 ? Gi : Gii,(mod - 1) / (mid << 1));
for (Int R = mid << 1,j = 0; j < limit; j += R)
{
for (Int k = 0,w = 1; k < mid; ++ k,w = 1ll * w * Wn % mod)
{
int x = a[j + k],y = 1ll * w * a[j + k + mid] % mod;
a[j + k] = (x + y) % mod,a[j + k + mid] = (x + mod - y) % mod;
}
}
}
if (type == 1) return ;
int Inv = quick_pow (limit,mod - 2);
for (Int i = 0; i < limit; ++ i) a[i] = 1ll * a[i] * Inv % mod;
}
int c[MAXN];
inline void Solve (int len,int *a,int *b)
{
if (len == 1) return b[0] = quick_pow (a[0],mod - 2),void ();
Solve ((len + 1) >> 1,a,b);
limit = 1,l = 0;
while (limit < (len << 1)) limit <<= 1,l ++;
for (Int i = 0; i < limit; ++ i) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
for (Int i = 0; i < len; ++ i) c[i] = a[i];
for (Int i = len; i < limit; ++ i) c[i] = 0;
NTT (c,1);
NTT (b,1);
for (Int i = 0; i < limit; ++ i) b[i] = 1ll * b[i] * (2 + mod - 1ll * c[i] * b[i] % mod) % mod;
NTT (b,-1);
for (Int i = len; i < limit; ++ i) b[i] = 0;
}
inline void deravitive (int *a,int n)
{
for (Int i = 1; i <= n; ++ i) a[i - 1] = 1ll * a[i] * i % mod;
a[n] = 0;
}
inline void inter (int *a,int n)
{
for (Int i = n; i >= 1; -- i) a[i] = 1ll * a[i - 1] * quick_pow (i,mod - 2) % mod;
a[0] = 0;
}
int b[MAXN];
inline void Ln (int *a,int n)
{
memset (b,0,sizeof (b));
Solve (n,a,b);
deravitive (a,n);
while (limit <= n) limit <<= 1,l ++;
for (Int i = 0; i < limit; ++ i) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
NTT (a,1),NTT (b,1);
for (Int i = 0; i < limit; ++ i) a[i] = 1ll * a[i] * b[i] % mod;
NTT (a,-1),inter (a,n);
for (Int i = n + 1; i < limit; ++ i) a[i] = 0;
}
int F0[MAXN];
inline void Exp (int *a,int *B,int n)
{
if (n == 1) return B[0] = 1,void ();
Exp (a,B,(n + 1) >> 1);
for (Int i = 0; i < limit; ++ i) F0[i] = B[i];
Ln (F0,n);
F0[0] = (a[0] + 1 + mod - F0[0]) % mod;
for (Int i = 1; i < n; ++ i) F0[i] = (a[i] + mod - F0[i]) % mod;
NTT (F0,1);
NTT (B,1);
for (Int i = 0; i < limit; ++ i) B[i] = 1ll * F0[i] * B[i] % mod;
NTT (B,-1);
for (Int i = n; i < limit; ++ i) B[i] = 0;
}
inline int read ()
{
int x = 0;
char c = getchar();
int f = 1;
while (c < '0' || c > '9')
{
if (c == '-') f = -f;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = (x << 3) + (x << 1) + c - '0';
c = getchar();
}
return x * f;
}
inline void write (int x)
{
if (x < 0)
{
x = -x;
putchar ('-');
}
if (x > 9) write (x / 10);
putchar (x % 10 + '0');
}
int fac[MAXN],caf[MAXN], lim = 512;
inline void init ()
{
fac[0] = 1;
memset(mp, -1, sizeof(mp));
for (Int i = 1; i <= lim; ++ i) fac[i] = 1ll * fac[i - 1] * i % mod;
caf[lim] = quick_pow (fac[lim],mod - 2);
for (Int i = lim; i; -- i) caf[i - 1] = 1ll * caf[i] * i % mod;
}
int H[MAXN],H_[MAXN],G[MAXN],FG[MAXN],SG[MAXN];
inline void makerev (int len)
{
limit = 1,l = 0;
while (limit < len) limit <<= 1,l ++;
for (Int i = 0; i < limit; ++ i) r[i] = (r[i >> 1] >> 1) | ((i & 1) << l - 1);
}
inline void prepare ()
{
int len = 1 << 9;
makerev (len);
for (Int i = 0; i < len; ++ i) H[i] = 1ll * quick_pow (2,1ll * i * (i - 1) / 2 % (mod - 1)) * caf[i] % mod;
Ln (H,len - 1);
for (Int i = 0; i < len; ++ i) H[i] = H_[i] = 1ll * H[i] * i % mod;
deravitive (H_,len - 1),makerev (len << 1),NTT (H_,1);
}
inline int work (int n)
{
int len = 1 << 9;
memset (SG,0,sizeof (SG)),memset (F0,0,sizeof (F0));
for (Int i = 0; i < len; ++ i) G[i] = 1ll * H[i] * (mod - n) % mod;
Exp (G,SG,len),makerev (len << 1),NTT (SG,1);
for (Int i = 0; i < len << 1; ++ i) SG[i] = 1ll * SG[i] * H_[i] % mod;
NTT (SG,-1);
return 1ll * SG[n - 1] * quick_pow (n,mod - 2) % mod * fac[n - 1] % mod;
}
int mp[maxn];
mint cal(int n) {
if (mp[n] != -1) return mp[n];
mp[n] = work(n);
return mp[n];
}
}go;
mint fac[maxn];
void solve(){
int n;
std::cin >> n;
// std::cerr << go.cal(1) << " " << go.cal(2) << " " << go.cal(3) << " " << go.cal(4) << "\n";
std::vector<int> a(n);
f[0][0] = 1;
choose[0][0] = 1;
fac[0] = 1;
for (int i = 1; i <= n; i += 1) {
choose[i][0] = 1;
fac[i] = fac[i - 1] * mint(i);
for (int j = 1; j <= i; j += 1) {
choose[i][j] = choose[i - 1][j] + choose[i - 1][j - 1];
}
}
g[0] = 1;
for (auto &x : a) {
std::cin >> x;
memset(new_g, 0, sizeof(new_g));
for (int i = 0; i <= n; i += 1) {
new_g[i] += g[i];
new_g[i + 1] += g[i] * mint(x);
}
memcpy(g, new_g, sizeof(g));
}
// ff[0] = 1;
// for (int i = 1; i <= n; i += 1) {
// ff[i] = power(mint(2), i * (i - 1) / 2);
// for (int j = 1; j < i; j += 1) {
// ff[i] -= ff[j] * choose[i - 1][j - 1] * power(mint(2), (i - j) * (i - j - 1) / 2);
// }
// }
// for (int i = 1; i <= n; i += 1) {
// f[i][0] = ff[i];
// for (int j = 1; j <= i; j += 1) {
// for (int k = 1; k < i; k += 1) {
// f[i][j] += f[i - k][j - 1] * f[k][0] * (i - k) * k * choose[i - 1][k - 1];
// }
// f[i][0] -= f[i][j];
// }
// }
dp[1][1] = 1;
for (int i = 2; i <= n; i += 1) {
memset(new_dp, 0, sizeof(new_dp));
for (int j = 1; j <= i; j += 1) {
for (int k = 1; k <= i; k += 1) {
new_dp[j][k + 1] += dp[j][k];
// new_dp[j + 1][1] += dp[j][k] * k * f[k][0];
new_dp[j + 1][1] += dp[j][k] * mint(k) * go.cal(k) / (fac[k - 1]);
}
}
memcpy(dp, new_dp, sizeof(dp));
}
mint res = 0;
for (int i = 1; i <= n; i += 1) {
for (int j = 1; j <= n; j += 1) {
mint cur = dp[i][j] * go.cal(j) * g[i] / (fac[j - 1]) * fac[n - i];
if (i > 1) {
cur *= mint(j) * power(mint(n), i - 2);
}
res += cur;
// std::cerr << i << " " << j << " " << dp[i][j] << " " << g[i + 1] << " " << res << "\n";
}
}
std::cout << res << '\n';
}
int main(){
go.init();
go.prepare();
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
solve();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 6316kb
input:
3 8 5 9
output:
1102
result:
ok "1102"
Test #2:
score: 0
Accepted
time: 3ms
memory: 6340kb
input:
5 4 2 1 3 10
output:
63860
result:
ok "63860"
Test #3:
score: 0
Accepted
time: 6ms
memory: 6252kb
input:
7 229520041 118275986 281963154 784360383 478705114 655222915 970715006
output:
35376232
result:
ok "35376232"
Test #4:
score: 0
Accepted
time: 1493ms
memory: 6260kb
input:
300 7 8 2 8 6 5 5 3 2 3 8 0 6 0 1 0 10 7 10 0 1 0 6 7 2 6 4 7 9 4 6 5 5 9 8 5 4 5 3 5 4 4 10 2 4 9 7 5 2 2 5 6 3 6 8 2 8 3 6 2 5 1 10 3 0 7 1 9 6 5 10 0 3 0 2 4 2 7 6 10 1 0 0 9 4 3 5 5 2 6 1 8 5 4 0 0 5 8 8 1 3 9 9 9 8 1 4 10 7 4 8 5 0 4 3 4 4 8 1 6 1 10 9 3 2 5 0 0 5 2 7 5 4 10 3 5 10 10 7 6 10 3 ...
output:
409590176
result:
ok "409590176"
Test #5:
score: 0
Accepted
time: 1988ms
memory: 6496kb
input:
335 4 3 7 7 8 1 4 7 8 8 4 3 5 5 6 8 8 9 3 7 2 4 6 6 6 3 0 7 8 4 6 1 9 10 9 9 0 7 10 3 3 4 10 5 10 4 10 3 7 7 1 9 8 4 0 3 8 1 10 10 7 5 2 7 6 0 4 7 5 9 1 4 10 3 2 9 2 0 1 5 3 5 5 9 9 3 5 6 10 6 9 5 10 10 8 10 5 9 6 1 10 6 7 1 0 7 10 1 6 7 8 2 2 10 1 3 4 1 5 3 3 2 4 10 3 5 8 0 10 0 9 4 9 2 7 3 8 7 4 7...
output:
997747
result:
ok "997747"
Test #6:
score: 0
Accepted
time: 102ms
memory: 6340kb
input:
84 2 5 3 4 5 8 10 5 2 10 7 6 10 10 7 7 3 2 1 7 8 5 9 10 7 5 6 1 2 8 2 8 6 5 4 6 9 0 3 9 3 2 0 2 9 0 4 4 8 10 3 4 6 10 10 5 8 1 10 8 2 7 3 10 8 8 3 2 8 7 4 10 2 6 9 9 3 6 3 3 9 0 7 6
output:
182929290
result:
ok "182929290"
Test #7:
score: 0
Accepted
time: 59ms
memory: 6324kb
input:
54 9 2 1 10 6 6 10 4 7 6 0 3 8 10 5 7 8 6 1 10 9 6 1 8 0 4 2 7 4 0 9 8 5 3 0 4 3 6 1 8 4 1 4 9 6 6 8 0 8 0 0 7 6 9
output:
43066240
result:
ok "43066240"
Test #8:
score: 0
Accepted
time: 33ms
memory: 6212kb
input:
32 0 8 6 8 1 3 9 5 9 0 4 2 4 4 3 10 2 3 1 8 2 6 5 3 9 5 0 0 5 2 1 4
output:
718335570
result:
ok "718335570"
Test #9:
score: 0
Accepted
time: 3ms
memory: 6492kb
input:
1 998244352
output:
998244352
result:
ok "998244352"
Test #10:
score: -100
Time Limit Exceeded
input:
400 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244352 998244...