QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#316547#8180. Bridge Eliminationucup-team2112#TL 1821ms6348kbC++209.7kb2024-01-27 21:43:202024-01-27 21:43:21

Judging History

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

  • [2024-01-27 21:43:21]
  • 评测
  • 测评结果:TL
  • 用时:1821ms
  • 内存:6348kb
  • [2024-01-27 21:43:20]
  • 提交

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 = 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: 100
Accepted
time: 8ms
memory: 6308kb

input:

3
8 5 9

output:

1102

result:

ok "1102"

Test #2:

score: 0
Accepted
time: 11ms
memory: 6340kb

input:

5
4 2 1 3 10

output:

63860

result:

ok "63860"

Test #3:

score: 0
Accepted
time: 11ms
memory: 6224kb

input:

7
229520041 118275986 281963154 784360383 478705114 655222915 970715006

output:

35376232

result:

ok "35376232"

Test #4:

score: 0
Accepted
time: 1821ms
memory: 6348kb

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: -100
Time Limit Exceeded

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:


result: