Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #define fi first
- #define se second
- #define pb push_back
- #define pf push_front
- #define popb pop_back
- #define popf pop_front
- #define ins insert
- #define pq priority_queue
- #define minele min_element
- #define maxele max_element
- #define lb lower_bound //first pos >= val
- #define ub upper_bound // first pos > val
- #define cnt_bit __builtin_popcount
- #define debug(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
- using namespace std;
- typedef unsigned long long ll;
- typedef pair<ll, ll> pll;
- typedef pair<int, int> pii;
- int d4x[4] = {1, 0, -1, 0}; int d4y[4] = {0, 1, 0, -1};
- int d8x[8] = {0, 1, 1, 1, 0, -1, -1, -1};
- int d8y[8] = {1, 1, 0, -1, -1, -1, 0, 1};
- const ll oo = 1e18;
- const ll maxN = 1e6;
- const int LOG = 30;
- const int N = 1e5 + 2710;
- vector<pii> g[N];
- vector<int> son[N];
- int sz[N];
- ll cnt[LOG + 5][2];
- int child[N];
- ll num[N];
- ll ans = 0;
- void dfs_sub1(int u, int par, ll val) {
- ans += val;
- for(pii v : g[u]) {
- if(v.fi != par) {
- dfs_sub1(v.fi, u, val ^ v.se);
- }
- }
- }
- void sub1(int n) {
- for(int i = 1; i < n; i++) {
- int u, v, L;
- cin >> u >> v >> L;
- g[u].pb(make_pair(v, L)); g[v].pb(make_pair(u, L));
- }
- for(int i = 1; i <= n; i++) {
- dfs_sub1(i, 0, 0);
- }
- cout << ans / 2;
- }
- void dfssz(int u, int par) {
- sz[u] = 1;
- for(pii v : g[u]) {
- if(v.fi != par) {
- num[v.fi] = num[u] ^ v.se;
- dfssz(v.fi, u);
- sz[u] += sz[v.fi];
- }
- }
- }
- void dfs(int u, int par, bool isBig) {
- int big = 0; ll ed = 0;
- for(pii v : g[u]) {
- if(v.fi != par && sz[v.fi] > sz[big]) big = v.fi, ed = v.se;
- }
- for(pii v : g[u]) {
- if(v.fi != par && v.fi != big) dfs(v.fi, u, false);
- }
- if(big > 0) {
- dfs(big, u, true);
- swap(son[u], son[big]);
- }
- for(int i = 0; i <= LOG; i++) {
- int p = (ed >> i & 1);
- if(p > 0) swap(cnt[i][0], cnt[i][1]);
- ans += 1ll * (1ll << i) * cnt[i][1];
- ++cnt[i][0];
- }
- son[u].pb(u);
- for(pii v : g[u]) {
- if(v.fi != par && v.fi != big) {
- int iter = 0;
- for(auto c : son[v.fi]) {
- ll curr = num[c] ^ num[u];
- for(int i = 0; i <= LOG; i++) {
- int p = (curr >> i & 1);
- ans += 1ll * (1ll << i) * cnt[i][p ^ 1];
- }
- child[++iter] = c;
- }
- for(int i = 1; i <= iter; i++) {
- son[u].pb(child[i]);
- ll curr = num[child[i]] ^ num[u];
- for(int j = 0; j <= LOG; j++) {
- int p = (curr >> j & 1);
- ++cnt[j][p];
- }
- }
- }
- }
- // cout << debug(u) debug(ans) << endl;
- // for(int i = 0; i <= 3; i++) {
- // cout << debug(i) debug(cnt[i][0]) debug(cnt[i][1]) << endl;
- // }
- if(!isBig) {
- for(int i = 0; i <= LOG; i++) cnt[i][0] = cnt[i][1] = 0;
- }
- }
- void sub3(int n) {
- for(int i = 1; i < n; i++) {
- int u, v, L;
- cin >> u >> v >> L;
- g[u].pb(make_pair(v, L)); g[v].pb(make_pair(u, L));
- }
- dfssz(1, 0);
- dfs(1, 0, 1);
- cout << ans;
- }
- void solve() {
- int n; cin >> n;
- if(n <= 3000) {
- sub1(n);
- return;
- }
- //DSU ON TREE
- sub3(n);
- }
- int main()
- {
- ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
- //freopen("XTREEW.inp", "r", stdin);
- //freopen("XTREEW.out", "w", stdout);
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement