E. Triangle Tree

E. Triangle Tree

You are given a rooted tree containing n vertices rooted at vertex 1. A pair of vertices (u,v) is called a good pair if u is not an ancestor of v and v is not an ancestor of u. For any two vertices, dist(u,v) is defined as the number of edges on the unique simple path from u to v, and lca(u,v) is defined as their lowest common ancestor.

A function f(u,v) is defined as follows.

  • If (u,v) is a good pair, f(u,v) is the number of distinct integer values x such that there exists a non-degenerate triangle formed by side lengths dist(u,lca(u,v)), dist(v,lca(u,v)), and x.
  • Otherwise, f(u,v) is 0.

You need to find the following value: i=1n1j=i+1nf(i,j).

A tree is a connected graph without cycles. A rooted tree is a tree where one vertex is special and called the root.

An ancestor of vertex v is any vertex on the simple path from v to the root, including the root, but not including v. The root has no ancestors.

A triangle with side lengths a, b, c is non-degenerate when a+b>c, a+c>b, b+c>a.

Input

Each test contains multiple test cases. The first line contains the number of test cases t (1t104). The description of the test cases follows.

The first line of each test case contains a single integer n (1n3105).

Each of the next n1 lines contains two integers ui and vi, denoting the two vertices connected by an edge (1ui,vin, uivi).

It is guaranteed that the given edges form a tree.

It is guaranteed that the sum of n over all test cases does not exceed 3105.

Output

For each test case, output the answer on a separate line.

Example

Input

4
3
1 2
1 3
3
1 2
3 2
5
2 3
1 5
4 2
1 2
11
2 1
2 3
2 4
4 5
6 5
5 7
4 8
8 9
7 10
10 11

Output

1
0
4
29

Note

On the first test case, the only good pair (i,j) satisfying i<j is (2,3). Here, lca(2,3) is 1, and the two distances are 1 and 1.

There is only one value of x for two side lengths 1 and 1, which is 1. Therefore, the answer for the first test case is 1.

On the second test case, there is no good pair. Therefore, the answer for the second test case is 0.

On the third test case, the good pairs (i,j) satisfying i<j are as follows.

  • (2,5): lca(2,5) is 1, distances are 1 and 1. There is only one possible value of x, which is 1.
  • (3,4): lca(3,4) is 2, distances are 1 and 1. There is only one possible value of x, which is 1.
  • (3,5): lca(3,5) is 1, distances are 2 and 1. There is only one possible value of x, which is 2.
  • (4,5): lca(4,5) is 1, distances are 2 and 1. There is only one possible value of x, which is 2.

Therefore, the answer for the third test case is 1+1+1+1=4.

 

解题思路

  定义 du 表示节点 u 到根节点的距离。如果 (u,v) 合法,记 lca(u,v)pa=dudpb=dvdp 为三角形的两条边(不失一般性假设 ab),那么另一条边需要满足 {a+bx+1a+xb+1,解得 ba+1xa+b1,因此 x 的取值有 2a1 种。所以有

f(u,v)=2min{dudp,dvdp}1=2min{du,dv}(2dp+1)

  可以分别处理 uv2min{du,dv}uv2dp+1 这两部分。在求解前先进行一次 dfs,求出 du,子树 u 的大小 szu,深度为 i 的节点数量 ci。定义后缀和 si=j=incj

  对于 uv2min{du,dv},枚举每个节点 u,然后求出满足 dudv 的节点 v 的数量 sdu。需要注意的是这些节点包括子树 u 的所有节点(子树的每个节点深度必然比 u 大),因此需要减去 szu,否则会统计不合法的 (u,v)。因此有 2du(sduszu)。还有一个小问题,当 du=dvf(u,v) 会被统计两次,因此需要进行容斥,对于每个深度 i 只需减去 2iCci2 即可。所以 uv2min{du,dv}=u2du(sduszu)i=1n2iCci2

  对于 uv2dp+1,只需枚举每个节点 u 作为 lca,求出 lca 为 u 的合法数对数量,乘以 2dp+1 即可。假设 u 的子节点为 v1,v2,,vm,那么 i=1mszvij=1i1szvj 即为所求数量,记为 tu。因此 uv2dp+1=u(2du+1)tu

  AC 代码如下,时间复杂度为 O(n)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 3e5 + 5, M = N * 2;

int h[N], e[M], ne[M], idx;
int d[N], sz[N], s[N];
LL ans;

void add(int u, int v) {
    e[idx] = v, ne[idx] = h[u], h[u] = idx++;
}

void dfs(int u, int p) {
    d[u] = d[p] + 1;
    s[d[u]]++;
    for (int i = h[u]; i != -1; i = ne[i]) {
        int v = e[i];
        if (v == p) continue;
        dfs(v, u);
        ans -= (2ll * d[u] + 1) * sz[u] * sz[v];
        sz[u] += sz[v];
    }
    sz[u]++;
}

void solve() {
    int n;
    cin >> n;
    idx = 0;
    memset(h, -1, n + 1 << 2);
    for (int i = 0; i < n - 1; i++) {
        int u, v;
        cin >> u >> v;
        add(u, v), add(v, u);
    }
    ans = 0;
    memset(sz, 0, n + 1 << 2);
    memset(s, 0, n + 2 << 2);
    dfs(1, 0);
    for (int i = n; i; i--) {
        ans -= s[i] * (s[i] - 1ll) * i;
        s[i] += s[i + 1];
    }
    for (int i = 1; i <= n; i++) {
        ans += 2ll * d[i] * (s[d[i]] - sz[i]);
    }
    cout << ans << '\n';
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Codeforces Round 1000 (Div. 2) — Editorial:https://codeforces.com/blog/entry/138593

posted @   onlyblues  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2023-01-28 斐波那契前 n 项和
2023-01-28 最幸运的数字
2022-01-28 圆形牛棚
Web Analytics
点击右上角即可分享
微信分享提示