Source Code
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
#include <unordered_map>
//#include"testlib.h"
#define endl '\n'
#define all(v) v.begin(),v.end()
#define allr(s) s.rbegin(),s.rend()
#define RT(s) return cout<<s,0
#define sz(s)    (int)(s.size())
//#define PI acos(-1)
#define EPS 1e-8
#define watch(x) cout << (#x)<<" = "<<x<<endl
#define mk(x, y) make_pair(x, y)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
int dy[] = { 1, -1, 0, 0, -1, 1, 1, -1 };
int dx[] = { 0, 0, 1, -1, 1, -1, 1, -1 };
void file() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	//freopen("C:\\Users\\karemo\\source\\repos\\generator\\generator\\out.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#else
	//freopen("gcd.in", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif
}


void fast() {
	std::ios_base::sync_with_stdio(0);
	cin.tie(NULL);
}
const int N = 1e5 + 1;
int dp1[N][2], dp2[N][2];
int n, mod = 1e9 + 7, bit;
void dfs1(int u, int par, vector<vii>& adjL, int dp[][2]) {
	dp[u][0] = dp[u][1] = 0;
	for (auto& v : adjL[u]) {
		if (v.first == par)
			continue;

		dfs1(v.first, u, adjL, dp);
		int num = (v.second & (1 << bit)) != 0;
		dp[u][num]++;
		dp[u][0] += dp[v.first][0 ^ num];
		dp[u][1] += dp[v.first][1 ^ num];
	}
}
void dfs2(int u, int par, int num, vector<vii>& adjL, int dp[][2]) {
	if (par != -1) {
		int tmp[2];
		tmp[0] = dp[par][0], tmp[1] = dp[par][1];
		tmp[num]--;
		tmp[0] -= dp[u][0 ^ num];
		tmp[1] -= dp[u][1 ^ num];
		
		dp[u][num]++;
		dp[u][0] += tmp[0 ^ num];
		dp[u][1] += tmp[1 ^ num];
	}
	for (auto& v : adjL[u])
		if (v.first != par)
			dfs2(v.first, u, (v.second & (1 << bit)) != 0, adjL, dp);
}
int main() {
	file();
	fast();
	cin >> n;
	vector<vii> adjL1(n + 1);
	vector<vii>adjL2(n + 1);
	for (int i = 0; i < n - 1; i++) {
		int u, v, w; cin >> u >> v >> w;
		adjL1[u].push_back({ v, w });
		adjL1[v].push_back({ u, w });
	}
	for (int i = 0; i < n - 1; i++) {
		int u, v, w; cin >> u >> v >> w;
		adjL2[u].push_back({ v, w });
		adjL2[v].push_back({ u, w });
	}
	int ans = 0;
	for (bit = 0; bit < 30; bit++) {

		dfs1(1,-1, adjL1, dp1);
		dfs2(1,-1, 0, adjL1, dp1);
			
		dfs1(1,-1, adjL2, dp2);
		dfs2(1,-1, 0, adjL2, dp2);

		for (int i = 1; i <= n; i++)
			dp1[i][0]++, dp2[i][0]++;
		for (int v = 1; v <= n; v++) {
			int cnt = dp1[v][1] * 1LL * dp2[v][0] % mod;
			int add1 = cnt * 1LL * (1 << bit) % mod;
			cnt = dp1[v][0] * 1LL * dp2[v][1] % mod;
			int add2 = cnt * 1LL * (1 << bit) % mod;
			add2 = (add2 + add1) % mod;
			ans = (ans + add2) % mod;
		}
	}
	cout << ans << endl;
	return 0;
}
Copy
Trees xOr karemo
GNU G++17
3406 ms
14.1 MB
Accepted