Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #include <ext/pb_ds/assoc_container.hpp>
- #include <ext/pb_ds/tree_policy.hpp>
- using namespace std;
- using namespace __gnu_pbds;
- #define debug(x) cerr << '[' << (#x) << "] = " << x << '\n';
- template<class T> using ordered_set = tree<T, null_type , less<T> , rb_tree_tag , tree_order_statistics_node_update> ;
- const int maxn = 1e5 + 5;
- vector<int>g[maxn];
- void PlayGround() {
- int N;
- cin >> N;
- vector<pair<int,pair<int,int>>>edges(N-1);
- for(auto& it : edges) {
- cin >> it.second.first >> it.second.second >> it.first;
- g[it.second.first].push_back(it.second.second);
- g[it.second.second].push_back(it.second.first);
- }
- sort(edges.begin(), edges.end());
- vector<int>tin(N+1), tout(N+1);
- int timer = 1;
- function<void(int,int)> DFS = [&] (int node, int parent) {
- tin[node] = timer++;
- for(auto it : g[node]) if(it != parent) {
- DFS(it, node);
- }
- tout[node] = timer++;
- };
- DFS(1, 1);
- auto isAncestor = [&] (int u, int v) {
- return tin[u] <= tin[v] && tout[u] >= tout[v];
- };
- for(auto& it : edges) {
- if(!isAncestor(it.second.first, it.second.second))
- swap(it.second.first, it.second.second);
- }
- struct Qu{
- int u, v, k, idx;
- bool operator< (Qu o) const {
- return make_tuple(k, u, v, idx) < make_tuple(o.k, o.u, o.v, o.idx);
- };
- };
- int M;
- cin >> M;
- vector<Qu>ask(M);
- vector<int>segmentTree(N<<3), lazy(N<<3);
- auto propagate = [&] (int node) {
- segmentTree[node+node] ^= lazy[node];
- segmentTree[node+node+1] ^= lazy[node];
- lazy[node+node] ^= lazy[node];
- lazy[node+node+1] ^= lazy[node];
- lazy[node] = 0;
- };
- function<void(int,int,int,int,int,int)> Update = [&] (int l, int r, int L, int R, int val, int node) {
- if(l>=L && r<=R) {
- segmentTree[node] ^= val;
- lazy[node] ^= val;
- return;
- }
- if(l>R || r<L) return;
- int mid = (l+r)>>1;
- if(lazy[node]) propagate(node);
- Update(l, mid, L, R, val, node+node);
- Update(mid+1, r, L, R, val, node+node+1);
- segmentTree[node] = segmentTree[node+node] ^ segmentTree[node+node+1];
- };
- function<int(int,int,int,int)> Query = [&] (int l, int r, int tar, int node) {
- if(l==r) {
- return segmentTree[node];
- }
- int mid = (l+r)>>1;
- if(lazy[node]) propagate(node);
- if(tar <= mid) return Query(l, mid, tar, node+node);
- else return Query(mid+1, r, tar, node+node+1);
- };
- for(int i=0; i<M; ++i) {
- int u, v, k; cin >> u >> v >> k;
- Qu q = {u, v, k, i};
- ask[i] = q;
- }
- sort(ask.begin(), ask.end());
- vector<int>answers(M);
- auto it = edges.begin();
- for(int i=0; i<M; ++i) {
- int val = ask[i].k;
- auto upto = upper_bound(edges.begin(), edges.end(), make_pair(val, make_pair(INT_MAX, INT_MAX)));
- while(it != upto) {
- Update(1, N+N, tin[it->second.second], tout[it->second.second], it->first, 1);
- ++it;
- }
- answers[ask[i].idx] = (Query(1, N+N, tin[ask[i].u], 1) ^ Query(1, N+N, tin[ask[i].v], 1));
- }
- for(int it : answers) cout << it << ' ';
- for(int i=1; i<=N; ++i) g[i].clear();
- cout << '\n';
- #ifndef ONLINE_JUDGE
- cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
- #endif
- }
- int main() {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- #ifndef ONLINE_JUDGE
- freopen("input.txt", "r", stdin);
- #endif
- int T;
- cin >> T;
- while(T--)
- PlayGround();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement