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

  •  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
 */

 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值