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> ;
- void PlayGround() {
- int N, Q;
- cin >> N >> Q;
- int vals[N+1];
- vector<vector<int>>edges(N+1, vector<int>());
- for(int i=1; i<=N; ++i) cin >> vals[i];
- for(int i=1; i<N; ++i) {
- int u, v; cin >> u >> v;
- edges[u].push_back(v);
- edges[v].push_back(u);
- }
- int timer = 1, l = 20;
- vector<vector<int>>up(N+1, vector<int>(l+1));
- vector<int>tin(N+1), tout(N+1);
- function<void(int,int)> DFS = [&] (int node, int parent) {
- tin[node] = timer++;
- up[node][0] = parent;
- for(int i=1; i<=l; ++i) {
- up[node][i] = up[up[node][i-1]][i-1];
- }
- for(auto it : edges[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];
- };
- auto getLCA = [&] (int u, int v) {
- if(isAncestor(u, v)) return u;
- if(isAncestor(v, u)) return v;
- for(int i=l; i>-1; --i) if(!isAncestor(up[u][i], v)) {
- u = up[u][i];
- }
- return up[u][0];
- };
- vector<int>segmentTree(N<<3), lazy(N<<3);
- auto propagate = [&] (int node) {
- lazy[node+node] ^= lazy[node];
- lazy[node+node+1] ^= lazy[node];
- segmentTree[node+node] ^= lazy[node];
- segmentTree[node+node+1] ^= lazy[node];
- lazy[node] = 0;
- };
- 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);
- };
- 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];
- };
- for(int i=1; i<=N; ++i) {
- Update(1, N+N, tin[i], tout[i], vals[i], 1);
- }
- while(Q--) {
- int t; cin >> t;
- if(t==1) {
- int i, v; cin >> i >> v;
- Update(1, N+N, tin[i], tout[i], vals[i], 1);
- Update(1, N+N, tin[i], tout[i], v, 1);
- vals[i] = v;
- } else {
- int u, v; cin >> u >> v;
- int lca = getLCA(u, v);
- cout << (vals[lca] ^ Query(1, N+N, tin[u], 1) ^ Query(1, N+N, tin[v], 1)) << '\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);
- freopen("cowland.in", "r", stdin);
- freopen("cowland.out", "w", stdout);
- #endif
- PlayGround();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement