QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#936566#10215. Gona Gunithinking (Fedor Romashov, Alexey Mikhnenko, Gimran Abdullin)#AC ✓896ms71808kbC++2011.1kb2025-03-15 21:24:512025-03-15 21:24:58

Judging History

This is the latest submission verdict.

  • [2025-03-15 21:24:58]
  • Judged
  • Verdict: AC
  • Time: 896ms
  • Memory: 71808kb
  • [2025-03-15 21:24:51]
  • Submitted

answer

#pragma GCC optimize("Ofast")

#include "bits/stdc++.h"


#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i < (n); ++i)
#define rep1n(i, n) for (int i = 1; i <= (n); ++i)
#define repr(i, n) for (int i = (n) - 1; i >= 0; --i)
//#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define each(x, a) for (auto &x : a)
#define ar array
#define vec vector
#define range(i, n) rep(i, n)

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using str = string;
using pi = pair<int, int>;
using pl = pair<ll, ll>;

using vi = vector<int>;
using vl = vector<ll>;
using vpi = vector<pair<int, int>>;
using vvi = vector<vi>;

int Bit(int mask, int b) { return (mask >> b) & 1; }

template<class T>
bool ckmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
bool ckmax(T &a, const T &b) {
    if (b > a) {
        a = b;
        return true;
    }
    return false;
}

// [l, r)
template<typename T, typename F>
T FindFirstTrue(T l, T r, const F &predicat) {
    --l;
    while (r - l > 1) {
        T mid = l + (r - l) / 2;
        if (predicat(mid)) {
            r = mid;
        } else {
            l = mid;
        }
    }
    return r;
}


template<typename T, typename F>
T FindLastFalse(T l, T r, const F &predicat) {
    return FindFirstTrue(l, r, predicat) - 1;
}

const int INFi = 2e9;
const ll INF = 2e18;

/*
 ! WARNING: MOD must be prime if you use division or .inv().
 ! WARNING: 2 * (MOD - 1) must be smaller than INT_MAX
 * Use .value to get the stored value.
 */
template<typename T>
int normalize(T value, int mod) {
    if (value < -mod || value >= 2 * mod) value %= mod;
    if (value < 0) value += mod;
    if (value >= mod) value -= mod;
    return value;
}

template<int mod>
struct static_modular_int {
    static_assert(mod - 2 <= std::numeric_limits<int>::max() - mod, "2(mod - 1) <= INT_MAX");
    using mint = static_modular_int<mod>;

    int value;

    static_modular_int() : value(0) {}
    static_modular_int(const mint &x) : value(x.value) {}

    template<typename T, typename U = std::enable_if_t<std::is_integral<T>::value>>
    static_modular_int(T value) : value(normalize(value, mod)) {}

    static constexpr int get_mod() {
        return mod;
    }

    template<typename T>
    mint power(T degree) const {
        mint prod = 1, a = *this;
        for (; degree > 0; degree >>= 1, a *= a)
            if (degree & 1)
                prod *= a;

        return prod;
    }

    mint inv() const {
        return power(mod - 2);
    }

    mint& operator=(const mint &x) {
        value = x.value;
        return *this;
    }

    mint& operator+=(const mint &x) {
        value += x.value;
        if (value >= mod) value -= mod;
        return *this;
    }

    mint& operator-=(const mint &x) {
        value -= x.value;
        if (value < 0) value += mod;
        return *this;
    }

    mint& operator*=(const mint &x) {
        value = int64_t(value) * x.value % mod;
        return *this;
    }

    mint& operator/=(const mint &x) {
        return *this *= x.inv();
    }

    friend mint operator+(const mint &x, const mint &y) {
        return mint(x) += y;
    }

    friend mint operator-(const mint &x, const mint &y) {
        return mint(x) -= y;
    }

    friend mint operator*(const mint &x, const mint &y) {
        return mint(x) *= y;
    }

    friend mint operator/(const mint &x, const mint &y) {
        return mint(x) /= y;
    }

    mint& operator++() {
        ++value;
        if (value == mod) value = 0;
        return *this;
    }

    mint& operator--() {
        --value;
        if (value == -1) value = mod - 1;
        return *this;
    }

    mint operator++(int) {
        mint prev = *this;
        value++;
        if (value == mod) value = 0;
        return prev;
    }

    mint operator--(int) {
        mint prev = *this;
        value--;
        if (value == -1) value = mod - 1;
        return prev;
    }

    mint operator-() const {
        return mint(0) - *this;
    }

    bool operator==(const mint &x) const {
        return value == x.value;
    }

    bool operator!=(const mint &x) const {
        return value != x.value;
    }

    bool operator<(const mint &x) const {
        return value < x.value;
    }

    template<typename T>
    explicit operator T() {
        return value;
    }

    friend std::istream& operator>>(std::istream &in, mint &x) {
        std::string s;
        in >> s;
        x = 0;
        bool neg = s[0] == '-';
        for (const auto c : s)
            if (c != '-')
                x = x * 10 + (c - '0');

        if (neg)
            x *= -1;

        return in;
    }

    friend std::ostream& operator<<(std::ostream &out, const mint &x) {
        return out << x.value;
    }

    static int primitive_root() {
        if constexpr (mod == 1'000'000'007)
            return 5;
        if constexpr (mod == 998'244'353)
            return 3;
        if constexpr (mod == 786433)
            return 10;

        static int root = -1;
        if (root != -1)
            return root;

        std::vector<int> primes;
        int value = mod - 1;
        for (int i = 2; i * i <= value; i++)
            if (value % i == 0) {
                primes.push_back(i);
                while (value % i == 0)
                    value /= i;
            }

        if (value != 1)
            primes.push_back(value);

        for (int r = 2;; r++) {
            bool ok = true;
            for (auto p : primes)
                if ((mint(r).power((mod - 1) / p)).value == 1) {
                    ok = false;
                    break;
                }

            if (ok)
                return root = r;
        }
    }
};

// constexpr int MOD = 1'000'000'007;
 constexpr int MOD = 998'244'353;
using mint = static_modular_int<MOD>;

/*
 ! WARNING: MOD must be prime.
 * Define modular int class above it.
 * No need to run any init function, it dynamically resizes the data.
 */
namespace combinatorics {
    std::vector<mint> fact_, ifact_, inv_;

    void resize_data(int size) {
        if (fact_.empty()) {
            fact_ = {mint(1), mint(1)};
            ifact_ = {mint(1), mint(1)};
            inv_ = {mint(0), mint(1)};
        }
        for (int pos = fact_.size(); pos <= size; pos++) {
            fact_.push_back(fact_.back() * mint(pos));
            inv_.push_back(-inv_[MOD % pos] * mint(MOD / pos));
            ifact_.push_back(ifact_.back() * inv_[pos]);
        }
    }

    struct combinatorics_info {
        std::vector<mint> &data;

        combinatorics_info(std::vector<mint> &data) : data(data) {}

        mint operator[](int pos) {
            if (pos >= static_cast<int>(data.size())) {
                resize_data(pos);
            }
            return data[pos];
        }
    } fact(fact_), ifact(ifact_), inv(inv_);

    // From n choose k.
    // O(max(n)) in total.
    mint choose(int n, int k) {
        if (n < k || k < 0 || n < 0) {
            return mint(0);
        }
        return fact[n] * ifact[k] * ifact[n - k];
    }

    // From n choose k.
    // O(min(k, n - k)).
    mint choose_slow(int64_t n, int64_t k) {
        if (n < k || k < 0 || n < 0) {
            return mint(0);
        }
        k = std::min(k, n - k);
        mint result = 1;
        for (int i = k; i >= 1; i--) {
            result *= (n - i + 1);
            result *= inv[i];
        }
        return result;
    }

    // Number of balanced bracket sequences with n open and m closing brackets.
    mint catalan(int n, int m) {
        if (m > n || m < 0) {
            return mint(0);
        }
        return choose(n + m, m) - choose(n + m, m - 1);
    }

    // Number of balanced bracket sequences with n open and closing brackets.
    mint catalan(int n) {
        return catalan(n, n);
    }
} // namespace combinatorics

using namespace combinatorics;


const int N = 3e5 + 5;
vector<mint> dp0[N], dp1[N];
vi g[N];
int m;

void Do(vector<mint> &s1, vector<mint> &s2, vector<mint> &out, int add=0) {
    if (s1.empty() || s2.empty()) return;
    int sz1 = s1.size();
    int sz2 = s2.size();
    int sz = min(m + 1, sz1 + sz2 + add - 1);
    if (out.size() < sz) {
        out.resize(sz);
    }

    for (int a = 0; a <= add; ++a) {
        int gm = m - a;
        for (int x = 0; x < sz1; ++x) {
            for (int y = 0; y < sz2 && x + y <= gm; ++y) {
                out[x + y + a] += s1[x] * s2[y];
            }
        }
    }
}

void Merge(int u, int v) {
    auto tmp0 = dp0[v];
    auto tmp1 = dp1[v];
    {
        // dp0[v][x+y] += dp0[v][x] * dp1[u][y]
        Do(dp0[v], dp1[u], tmp0);
    }
    {
        // dp1[v][x+y] += dp1[v][x] * (dp1[u][y] + dp0[u][y])
        Do(dp1[v], dp1[u], tmp1);
        Do(dp1[v], dp0[u], tmp1);
    }
    {
        // dp1[v][x+y] += dp0[v][x] * dp0[u][y]
        // dp1[v][x+y+1] += dp0[v][x] * dp0[u][y]
        Do(dp0[v], dp0[u], tmp1, 1);
    }

    swap(dp0[v], tmp0);
    swap(dp1[v], tmp1);
}

vector<mint> dp_tot;

void dfs(int v, int p) {
    dp0[v].push_back(2);
    for(auto &u : g[v]) {
        if (u == p) continue;
        dfs(u, v);

        Merge(u, v);
    }

    dp0[v][0] -= 1;

    rep(i, dp0[v].size()) dp_tot[i] += dp0[v][i];
    rep(i, dp1[v].size()) dp_tot[i] += dp1[v][i];

    for(auto &u : g[v]) {
        if (u == p) continue;

        // dp0[u] -> dp1[v]
        for(int y = 0; y < dp0[u].size(); ++y) {
            dp_tot[y] -= dp0[u][y];
            if (y + 1 <= m) dp_tot[y+1] -= dp0[u][y];
        }

        // dp1[u] -> dp0[v]
        for(int y = 0; y < dp1[u].size(); ++y) {
            dp_tot[y] -= dp1[u][y];
        }

        dp0[u].clear();
        dp0[u].shrink_to_fit();
        dp1[u].clear();
        dp1[u].shrink_to_fit();
    }

}

void solve() {
    int n; cin >> n >> m;
    rep(_, n - 1) {
        int u, v; cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dp_tot.resize(m + 1);
    rep(i, m + 1) dp_tot[i] = 0;
    dfs(1, -1);

    dp1[1].clear();
    dp0[1].clear();


    vector<vector<mint>> val(m + 1, vector<mint>(m + 1));
    val[0][0] = 1;
    for(int i = 1; i <= m; ++i) {
        for(int j = 0; j < i; ++j) {
            val[i][j] += val[i - 1][j] * j;
            val[i][j+1] += val[i-1][j];
        }
    }
    mint ans = 0;
    for(int i = 0; i < dp_tot.size(); ++i) {
        ans += dp_tot[i] * val[m][i] * fact[i];
    }

     cout << ans << '\n';

    for(int i = 1; i <= n; ++i) {
        g[i].clear();
    }
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout << setprecision(12) << fixed;
    int t = 1;

    cin >> t;
    rep(i, t) {
        solve();
    }

    return 0;
}

这程序好像有点Bug,我给组数据试试?

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 3712kb

input:

2
3 1
1 2
1 3
20 200
1 2
1 3
2 4
1 5
5 6
1 7
6 8
6 9
3 10
4 11
6 12
11 13
4 14
13 15
15 16
6 17
13 18
15 19
13 20

output:

4
286430678

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 387ms
memory: 43648kb

input:

1
300000 200
1 2
1 3
2 4
1 5
4 6
5 7
6 8
4 9
4 10
1 11
11 12
12 13
11 14
11 15
15 16
15 17
11 18
13 19
17 20
11 21
21 22
22 23
21 24
23 25
21 26
26 27
23 28
21 29
23 30
21 31
31 32
32 33
31 34
31 35
31 36
34 37
35 38
31 39
36 40
31 41
41 42
41 43
41 44
43 45
43 46
44 47
45 48
44 49
49 50
41 51
51 52...

output:

247999825

result:

ok single line: '247999825'

Test #3:

score: 0
Accepted
time: 153ms
memory: 4096kb

input:

3000
100 31
1 2
1 3
1 4
1 5
3 6
1 7
4 8
4 9
8 10
2 11
7 12
7 13
7 14
7 15
10 16
15 17
9 18
2 19
4 20
11 21
11 22
12 23
13 24
20 25
3 26
18 27
19 28
1 29
10 30
7 31
28 32
24 33
14 34
11 35
22 36
24 37
20 38
11 39
15 40
25 41
17 42
35 43
39 44
38 45
17 46
23 47
18 48
37 49
29 50
4 51
30 52
7 53
4 54
1...

output:

206703729
241517344
965256040
953191893
971103184
611763581
951769747
605254273
515657073
26158774
230121672
742384467
504292176
95015638
209242429
591984607
47728881
658540538
686302223
589359656
153765564
462000121
877695624
168867090
447225696
468677488
440776261
374615358
105981576
120340771
617...

result:

ok 3000 lines

Test #4:

score: 0
Accepted
time: 418ms
memory: 34816kb

input:

1
300000 200
1 2
2 3
1 4
2 5
5 6
4 7
5 8
8 9
3 10
2 11
10 12
12 13
4 14
6 15
6 16
7 17
13 18
3 19
13 20
18 21
5 22
22 23
20 24
24 25
24 26
9 27
25 28
5 29
5 30
20 31
21 32
24 33
7 34
22 35
32 36
30 37
26 38
30 39
39 40
24 41
37 42
28 43
37 44
16 45
27 46
7 47
16 48
38 49
7 50
29 51
47 52
4 53
31 54
...

output:

634171363

result:

ok single line: '634171363'

Test #5:

score: 0
Accepted
time: 896ms
memory: 71808kb

input:

1
300000 200
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
20 21
21 22
22 23
23 24
24 25
25 26
26 27
27 28
28 29
29 30
30 31
31 32
32 33
33 34
34 35
35 36
36 37
37 38
38 39
39 40
40 41
41 42
42 43
43 44
44 45
45 46
46 47
47 48
48 49
49 50
50 51
51 5...

output:

378891816

result:

ok single line: '378891816'

Test #6:

score: 0
Accepted
time: 278ms
memory: 30848kb

input:

1
300000 200
1 2
1 3
2 4
2 5
3 6
3 7
4 8
4 9
5 10
5 11
6 12
6 13
7 14
7 15
8 16
8 17
9 18
9 19
10 20
10 21
11 22
11 23
12 24
12 25
13 26
13 27
14 28
14 29
15 30
15 31
16 32
16 33
17 34
17 35
18 36
18 37
19 38
19 39
20 40
20 41
21 42
21 43
22 44
22 45
23 46
23 47
24 48
24 49
25 50
25 51
26 52
26 53
2...

output:

435358080

result:

ok single line: '435358080'

Test #7:

score: 0
Accepted
time: 510ms
memory: 42992kb

input:

1
300000 200
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
1 16
1 17
1 18
1 19
1 20
1 21
1 22
1 23
1 24
1 25
1 26
1 27
1 28
1 29
1 30
1 31
1 32
1 33
1 34
1 35
1 36
1 37
1 38
1 39
1 40
1 41
1 42
1 43
1 44
1 45
1 46
1 47
1 48
1 49
1 50
1 51
1 52
1 53
1 54
1 55
1 56
1 57
1 58
1 59
1 60
...

output:

220992079

result:

ok single line: '220992079'

Test #8:

score: 0
Accepted
time: 870ms
memory: 67968kb

input:

1
300000 200
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
20 21
21 22
22 23
23 24
24 25
25 26
26 27
27 28
28 29
29 30
30 31
31 32
32 33
33 34
34 35
35 36
36 37
37 38
38 39
39 40
40 41
41 42
42 43
43 44
44 45
45 46
46 47
47 48
48 49
49 50
50 51
51 5...

output:

872442796

result:

ok single line: '872442796'

Test #9:

score: 0
Accepted
time: 709ms
memory: 62336kb

input:

1
300000 200
1 2
1 3
3 4
3 5
5 6
5 7
7 8
7 9
9 10
9 11
11 12
11 13
13 14
13 15
15 16
15 17
17 18
17 19
19 20
19 21
21 22
21 23
23 24
23 25
25 26
25 27
27 28
27 29
29 30
29 31
31 32
31 33
33 34
33 35
35 36
35 37
37 38
37 39
39 40
39 41
41 42
41 43
43 44
43 45
45 46
45 47
47 48
47 49
49 50
49 51
51 52...

output:

77589834

result:

ok single line: '77589834'

Test #10:

score: 0
Accepted
time: 465ms
memory: 49792kb

input:

1
300000 200
1 2
1 3
2 4
1 5
1 6
6 7
6 8
8 9
9 10
6 11
11 12
11 13
13 14
11 15
11 16
16 17
17 18
17 19
18 20
16 21
21 22
22 23
22 24
24 25
21 26
26 27
26 28
26 29
27 30
26 31
31 32
31 33
33 34
31 35
31 36
36 37
37 38
36 39
39 40
36 41
41 42
42 43
42 44
44 45
41 46
46 47
46 48
46 49
48 50
46 51
51 52...

output:

137591617

result:

ok single line: '137591617'

Test #11:

score: 0
Accepted
time: 332ms
memory: 37248kb

input:

1
300000 200
1 2
1 3
2 4
1 5
4 6
5 7
6 8
4 9
4 10
3 11
8 12
1 13
7 14
8 15
14 16
7 17
7 18
16 19
3 20
12 21
13 22
9 23
13 24
18 25
10 26
11 27
12 28
13 29
15 30
22 31
23 32
8 33
4 34
16 35
13 36
24 37
6 38
27 39
7 40
39 41
37 42
10 43
37 44
40 45
9 46
16 47
7 48
24 49
34 50
45 51
46 52
43 53
53 54
5...

output:

529039223

result:

ok single line: '529039223'

Extra Test:

score: 0
Extra Test Passed