2019 ICPC西安邀请赛J. And And And【DFS计数】

    xiaoxiao2024-12-05  64

    2000ms 262144K

    A tree is a connected graph without cycles. You are given a rooted tree with nn nodes, labeled from 1 to n1ton. The tree is rooted at node 11. The parent of the ii-th node is f_{a_i}fai​​. The edge weight between the ii-th node and f_{a_i}fai​​ is w_iwi​

    E(u, v)E(u,v) is a set of all the nodes through a path which is from uu to vv, including uu and vv. For example,

    E(5,3) = \{5, 2, 1, 3\}, E(4,6) = \{4, 3, 6\}, E(2,5) = \{2,5\}E(5,3)={5,2,1,3},E(4,6)={4,3,6},E(2,5)={2,5}

    X(u, v)X(u,v) represents the XOR of all edge weights on the path from uu to vv

    For example, in the case given above,

    X(1,5) = 1X(1,5)=1 ⁡xorxor 1=01=0,X(4,6) = 1X(4,6)=1 ⁡xorxor 3=23=2,X(2,5) = 1X(2,5)=1,X(3,5) = 2X(3,5)=2 xorxor 11 xorxor 11 =2=2⁡You need to calculate the answer to the following formula:

    \displaystyle\sum_{u=1}^n \displaystyle\sum_{v=1}^n \displaystyle\sum_{u' \in E(u,v)} \displaystyle\sum_{v' \in E(u,v)} [u < v][ u' < v'][X(u',v')=0]u=1∑n​v=1∑n​u′∈E(u,v)∑​v′∈E(u,v)∑​[u<v][u′<v′][X(u′,v′)=0]

    The answer modulo 10000000071000000007

    XOR is equivalent to '^' in c / c++ / java / python. If both bits in the compared position of the bit patterns are 00 or 11, the bit in the resulting bit pattern is 00, otherwise 11.

    Input

    Each test file contains a single test case. In each test file:

    The first line contains one integer n(1 \le n \le 10^5)n(1≤n≤105) — the number of nodes in the tree.

    Then n - 1n−1 lines follow. ii-th line contains two integers f_{a_i}(1 \le f_{a_i} < i)fai​​(1≤fai​​<i), w_i(0 \le w_i \le 10^{18})wi​(0≤wi​≤1018) —The parent of the ii-th node and the edge weight between the ii-th node and f_{a_i} (ifai​​(i start from 2)2).

    Output

    Print a single integer — the answer of this problem, modulo 10000000071000000007.

    样例输入1复制

    2 12

    样例输出1复制

    0

    样例输入2复制

    5 1 0 2 0 3 0 4 0

    样例输出2复制

    35

     

     

    分析:计算贡献,对于任意两个点,如果这两个点之间的边异或为0,那么

    (1)如果这两个点其中一个是另一个的祖先,设v是u的祖先,x是与u在同一条链上的v的儿子,贡献=son(u)*(n-son(x))

    (2)否则贡献=son(u)*son(v)

    然后记录根到点的异或值,如果两个点到根的异或值相同的话,这两个点就会产生贡献,记录异或值的size,直接计数就可以了。

    #include "bits/stdc++.h" using namespace std; const int mod = 1e9 + 7; struct node { long long u, w; }; int num[100004]; vector<node> v[100004]; void dfs1(int u) { for (int i = 0; i < v[u].size(); ++i) { dfs1(v[u][i].u); num[u] += num[v[u][i].u] + 1; } } unordered_map<long long, long long> mp; unordered_map<long long, long long> mp1;//不同链 unordered_map<long long, long long> mp2;//同链 long long ans = 0; int n; void dfs2(int u, long long xo) { ans = (ans + mp1[xo] * (num[u] + 1) % mod) % mod; ans = (ans + mp2[xo] * (num[u] + 1) % mod) % mod; mp2[xo] += (n - num[u]); mp2[xo] %= mod; for (int i = 0; i < v[u].size(); ++i) { mp2[xo] = (mp2[xo] + num[u] - num[v[u][i].u] - 1) % mod; dfs2(v[u][i].u, xo ^ v[u][i].w); mp2[xo] = (mp2[xo] - num[u] + num[v[u][i].u] + 1 + mod) % mod; } mp2[xo] = (mp2[xo] - (n - num[u]) + mod) % mod; if (mp2[xo] == 0)mp2.erase(xo); mp1[xo] = (mp1[xo] + num[u] + 1) % mod; } int main() { scanf("%d", &n); long long u, w; for (int i = 2; i <= n; ++i) { scanf("%lld%lld", &u, &w); v[u].push_back({i, w}); } dfs1(1); dfs2(1, 0); cout << ans << endl; } /* * 6 1 1 1 2 3 1 2 1 3 3 6 1 0 1 0 3 0 2 0 3 0 */

     

    最新回复(0)