QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#715342#9530. A Game On TreeLivinflyTL 11ms6060kbC++172.8kb2024-11-06 11:32:572024-11-06 11:32:57

Judging History

This is the latest submission verdict.

  • [2024-11-06 11:32:57]
  • Judged
  • Verdict: TL
  • Time: 11ms
  • Memory: 6060kb
  • [2024-11-06 11:32:57]
  • Submitted

answer

// #pragma GCC optimize(2)

#include <bits/stdc++.h>

#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define mkp(x, y) make_pair((x), (y))
#define all(x) (x).begin(), (x).end()

using namespace std;

typedef long long LL;
typedef double db;
typedef pair<int, int> PII;

/*
sum[u],子树大小的平方和。
在 u 的子树中的点 v,找出两个点 x 和 y,
路径 u-x, u-y 的公共部分包含路径 u-v 的方案数

第二种贡献,第一种情况:
2 倍是有序对
(n-siz[v]) ^ 2 是公共边有 (u, v) 的一端的方案数
(sum[v]-siz[v]^2) 是 u 到子树的点的路径的方案数之和,
如 (u, .., x, y) 方案是 siz[y]^2,对应的是 (x, y) 的情况。

第二种情况:
sum[v1] * sum[v2],当理解了 sum 的意义后,也就理解了。
*/
const int N = 1e5+10, MO = 998244353;

vector<int> e[N];
int n, siz[N], sum[N], ans;

int square(int x) {
    return 1LL*x * x % MO;
}
void dfs(int u, int fr = -1) {
    siz[u] = 1, sum[u] = 0;
    for(auto v: e[u]) {
        if(v == fr) continue;
        dfs(v, u);
        siz[u] += siz[v];
        sum[u] += sum[v];
        if(sum[u] >= MO) sum[u] -= MO;
    }
    sum[u] += square(siz[u]) % MO;
    if(sum[u] >= MO) sum[u] -= MO;
}
void dfs0(int u, int fr = -1) {
    for(auto v: e[u]) {
        if(v == fr) continue;
        ans += 1LL*square(siz[v]) * square(n-siz[v]) % MO;
        if(ans >= MO) ans -= MO;
        ans += 2LL * square(n-siz[v]) * ((sum[v]-square(siz[v])) % MO + MO) % MO;
        if(ans >= MO) ans -= MO;
        dfs0(v, u);
    }
    for(auto v1: e[u]) {
        if(v1 == fr) continue;
        for(auto v2: e[u]) {
            if(v2 == fr) continue;
            if(v1 == v2) continue;
            ans += 1LL*sum[v1] * sum[v2] % MO;
            if(ans >= MO) ans -= MO;
        }
    }
}
int qpm(int a, int b, const int &c = MO) {
    int ans = 1;
    while(b) {
        if(b & 1) ans = 1LL*ans*a%MO;
        a = 1LL*a*a%MO;
        b >>= 1;
    }
    return ans;
}
void solve() {
    ans = 0;
    for(int i = 1; i <= n; i ++) {
        // vector<int>{}.swap(e[i]);
        e[i].clear();
    }
    cin >> n;
    for(int i = 1; i < n; i ++) {
        int u, v; cin >> u >> v;
        e[u].pb(v), e[v].pb(u);
    }
    dfs(1);
    dfs0(1);
    int tot = square(n*(n-1)/2 % MO);
    ans = 1LL*ans * qpm(tot, MO-2) % MO;
    cout << ans << '\n';
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed;  // << setprecision(20); // double
    // freopen("i.txt", "r", stdin);
    // freopen("o.txt", "w", stdout);
    // time_t t1 = clock();
    int Tcase = 1;
    cin >> Tcase; // scanf("%d", &Tcase);
    while (Tcase--) 
        solve();
    // cout << "time: " << 1000.0 * (1.*(clock() - t1) / CLOCKS_PER_SEC) << "ms\n";
    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 5976kb

input:

2
3
1 2
2 3
5
1 2
1 5
3 2
4 2

output:

443664158
918384806

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 2ms
memory: 6060kb

input:

1000
7
3 6
4 3
5 3
2 6
1 4
7 1
12
5 7
10 7
2 10
11 2
1 7
8 1
4 2
9 11
6 9
12 11
3 5
6
2 5
1 2
4 5
6 4
3 6
5
2 5
1 5
4 5
3 2
8
1 8
2 8
4 2
6 1
5 6
7 6
3 8
8
3 8
7 3
4 8
6 4
2 7
5 2
1 4
4
3 1
4 3
2 1
6
5 1
6 1
2 5
3 5
4 2
12
8 11
5 11
12 8
3 12
6 12
2 3
4 6
10 11
1 5
9 5
7 5
9
6 1
7 6
4 7
8 7
5 4
9 6
...

output:

948445317
468414020
550143557
918384806
711758412
487662742
776412276
869581749
240852807
765628773
211048577
887328316
890334966
940494682
760637552
908032643
592850815
584006902
908525604
221832080
433351719
56023919
867301808
183319566
698771049
366957926
449579681
599710576
310564911
286902823
3...

result:

ok 1000 lines

Test #3:

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

input:

1000
94
59 1
33 59
73 1
6 33
83 59
4 59
20 59
61 6
39 1
76 73
71 6
44 39
9 71
24 4
87 9
57 83
2 9
81 71
82 20
90 2
85 39
12 9
30 83
66 30
53 9
47 9
36 44
43 53
29 12
31 53
64 81
38 31
84 82
77 38
23 71
93 84
78 83
58 31
68 90
42 1
55 64
13 78
70 78
62 24
19 55
92 87
14 57
10 84
65 81
63 6
75 36
91 1...

output:

508107725
996793960
201633249
335988372
842755864
460619380
342223697
207523414
429241811
391691799
542977964
786416604
454278948
685531402
25914978
440729774
228518323
679471537
82764520
554190841
432505337
143444089
189106586
337234245
61954935
905141094
532919674
703954588
185671863
942858630
692...

result:

ok 1000 lines

Test #4:

score: -100
Time Limit Exceeded

input:

10000
8
1 4
3 1
5 1
7 3
8 4
6 8
2 7
8
2 6
4 6
5 6
8 5
7 6
3 5
1 7
8
8 5
6 5
2 5
7 2
1 6
3 1
4 8
9
8 6
9 8
3 6
1 8
5 9
2 8
4 3
7 9
8
8 6
3 6
5 8
1 6
4 3
7 6
2 6
9
9 5
7 5
2 7
8 7
4 9
3 7
6 3
1 4
8
1 4
5 1
6 5
3 4
8 4
7 8
2 5
9
1 8
6 1
2 1
3 8
5 3
9 8
7 8
4 8
9
4 9
2 9
1 2
3 4
5 2
6 9
8 3
7 2
8
1 2
8 ...

output:

49657566
56023919
387074343
97051536
701572244
211048577
711758412
308100110
761007271
711758412
178698065
285212675
80216065
43380497
267677376
818005792
53239701
765628773
970145625
387074343
436731906
422725927
479157293
977872021
436731906
925779210
487662742
705549251
267677376
711758412
526851...

result: