QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#316552#8180. Bridge Eliminationucup-team2112#TL 1988ms6496kbC++209.7kb2024-01-27 21:45:182024-01-27 21:45:18

Judging History

你现在查看的是最新测评结果

  • [2024-01-27 21:45:18]
  • 评测
  • 测评结果:TL
  • 用时:1988ms
  • 内存:6496kb
  • [2024-01-27 21:45:18]
  • 提交

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...

output:


result: