QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#316544 | #8180. Bridge Elimination | ucup-team2112# | RE | 0ms | 0kb | C++20 | 9.7kb | 2024-01-27 21:42:03 | 2024-01-27 21:42:03 |
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 = 1024;
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 = 1024;
inline void init ()
{
fac[0] = 1;
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 << 10;
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 << 10;
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;
}
map<int, mint> mp;
mint cal(int n) {
if (mp.count(n)) return mp[n];
return mp[n] = work(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: 0
Runtime Error
input:
3 8 5 9