Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintWriter;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.StringTokenizer;
- public class E {
- static FastReader scan;
- static PrintWriter out;
- public static void main(String[] args) throws FileNotFoundException {
- Solver solver = new Solver();
- scan = new FastReader("cowland.in");
- out = new PrintWriter("cowland.out");
- // scan = new FastReader();
- // out = new PrintWriter(System.out);
- int testCases = 1;
- for(int i = 1; i <= testCases; i++) {
- // out.print("Case #" + i + ": ");
- solver.solve();
- }
- out.close();
- }
- static class Solver {
- static int n, q;
- static long[] e, xor;
- static long[] tree, lazy;
- static int[] end, begin, depth, euler;
- static int[][] parent;
- static int index = 0;
- static ArrayList<Integer>[] adj;
- void solve() {
- n = scan.nextInt();
- q = scan.nextInt();
- e = scan.nextLongArray(n);
- xor = new long[n];
- tree = new long[4*n];
- lazy = new long[4*n];
- euler = new int[n];
- begin = new int[n];
- end = new int[n];
- depth = new int[n+1];
- parent = new int[n+1][18];
- for(int i = 0; i <= n; i++) Arrays.fill(parent[i], -1);
- adj = new ArrayList[n];
- for(int i = 0; i < n; i++) adj[i] = new ArrayList<>();
- for(int i = 0; i < n-1; i++) {
- int a = scan.nextInt()-1, b = scan.nextInt()-1;
- adj[a].add(b);
- adj[b].add(a);
- }
- go(-1,0,0,1);
- precompute();
- build(1, 0, n-1);
- for(int i = 0; i < q; i++) {
- int a = scan.nextInt(), b = scan.nextInt()-1, c = scan.nextInt()-1;
- if(a==1) {
- long d = c+1;
- update(1,0,n-1,begin[b],end[b],e[b]^d);
- e[b] = d;
- }
- else {
- long bb = get(1,0,n-1,begin[b],begin[b]);
- long cc = get(1,0,n-1,begin[c],begin[c]);
- out.println(bb^cc^e[lca(b,c)-1]);
- }
- }
- }
- static void update(int node, int s, int e, int l, int r, long val) {
- if(lazy[node] != 0) {
- if((s-e+1)%2==1) tree[node] ^= lazy[node];
- if(s != e) {
- lazy[2*node] ^= lazy[node];
- lazy[2*node+1] ^= lazy[node];
- }
- lazy[node] = 0;
- }
- if(s > e || s > r || e < l) return;
- if(s >= l && e <= r) {
- if((s-e+1)%2==1) tree[node] ^= val;
- if(s != e) {
- lazy[2*node] ^= val;
- lazy[2*node+1] ^= val;
- }
- return;
- }
- int mid = (s+e)/2;
- update(node*2,s,mid,l,r,val);
- update(node*2+1,mid+1,e,l,r,val);
- tree[node] = tree[2*node]^tree[2*node+1];
- }
- static long get(int node, int s, int e, int l, int r) {
- if(lazy[node] != 0) {
- if((s-e+1)%2==1) tree[node] ^= lazy[node];
- if(s != e) {
- lazy[2*node] ^= lazy[node];
- lazy[2*node+1] ^= lazy[node];
- }
- lazy[node] = 0;
- }
- if(s > e || s > r || e < l) return 0;
- if(s >= l && e <= r) {
- return tree[node];
- }
- int mid = (s+e)/2;
- long a = get(2*node,s,mid,l,r);
- long b = get(2*node+1,mid+1,e,l,r);
- return a^b;
- }
- static void build(int node, int s, int e) {
- if(s > e) return;
- if(s == e) {
- tree[node] = xor[euler[s]];
- return;
- }
- int mid = (s+e)/2;
- build(node*2,s,mid);
- build(node*2+1,mid+1,e);
- tree[node] = tree[2*node]^tree[2*node+1];
- }
- static void go(int p, int curr, long x, int at) {
- begin[curr] = index;
- euler[index] = curr;
- xor[curr] = x^e[curr];
- depth[curr+1] = at;
- parent[curr+1][0] = p+1;
- for(int i : adj[curr]) {
- if(i != p) {
- index++;
- go(curr, i, xor[curr], at+1);
- }
- }
- end[curr] = index;
- }
- static void precompute() {
- for(int i = 1; i < 18; i++) {
- for(int j = 1; j <= n; j++) {
- if(parent[j][i-1] != -1) {
- parent[j][i] = parent[parent[j][i-1]][i-1];
- }
- }
- }
- }
- static int lca(int a, int b) {
- a++;
- b++;
- if(depth[b] < depth[a]) {
- int temp = a;
- a = b;
- b = temp;
- }
- int diff = depth[b]-depth[a];
- for(int i = 0; i < 18; i++) {
- if(((diff>>i)&1) != 0) {
- b = parent[b][i];
- }
- }
- if(a==b) return a;
- for(int i = 17; i >= 0; i--) {
- if(parent[a][i] != parent[b][i]) {
- a = parent[a][i];
- b = parent[b][i];
- }
- }
- return parent[a][0];
- }
- }
- // Sathvik's Template Stuff BELOW!!!!!!!!!!!!!!!!!!!!!!
- static class DSU {
- int[] root, size;
- int n;
- DSU(int n) {
- this.n = n;
- root = new int[n];
- size = new int[n];
- for (int i = 0; i < n; i++) {
- root[i] = i;
- size[i] = 1;
- }
- }
- int findParent(int idx) {
- while (root[idx] != idx) {
- root[idx] = root[root[idx]];
- idx = root[idx];
- }
- return idx;
- }
- boolean union(int x, int y) {
- int parX = findParent(x);
- int parY = findParent(y);
- if (parX == parY)
- return false;
- if (size[parX] < size[parY]) {
- root[parY] = parX;
- size[parX] += size[parY];
- } else {
- root[parX] = parY;
- size[parY] += size[parX];
- }
- return true;
- }
- }
- static class Extra {
- static void sort(int[] a) {
- Integer[] aa = new Integer[a.length];
- for (int i = 0; i < aa.length; i++)
- aa[i] = a[i];
- Arrays.sort(aa);
- for (int i = 0; i < aa.length; i++)
- a[i] = aa[i];
- }
- static void sort(long[] a) {
- Long[] aa = new Long[a.length];
- for (int i = 0; i < aa.length; i++)
- aa[i] = a[i];
- Arrays.sort(aa);
- for (int i = 0; i < aa.length; i++)
- a[i] = aa[i];
- }
- static void sort(double[] a) {
- Double[] aa = new Double[a.length];
- for (int i = 0; i < aa.length; i++)
- aa[i] = a[i];
- Arrays.sort(aa);
- for (int i = 0; i < aa.length; i++)
- a[i] = aa[i];
- }
- static void sort(char[] a) {
- Character[] aa = new Character[a.length];
- for (int i = 0; i < aa.length; i++)
- aa[i] = a[i];
- Arrays.sort(aa);
- for (int i = 0; i < aa.length; i++)
- a[i] = aa[i];
- }
- static long gcd(long a, long b) {
- while (b > 0) {
- long temp = b;
- b = a % b;
- a = temp;
- }
- return a;
- }
- static long lcm(long a, long b) {
- return a * (b / gcd(a, b));
- }
- static boolean isPrime(long n) {
- if (n <= 1)
- return false;
- if (n <= 3)
- return true;
- if (n % 2 == 0 || n % 3 == 0)
- return false;
- for (long i = 5; i * i <= n; i = i + 6) {
- if (n % i == 0 || n % (i + 2) == 0)
- return false;
- }
- return true;
- }
- }
- static class FastReader {
- BufferedReader br;
- StringTokenizer st;
- public FastReader() {
- br = new BufferedReader(new InputStreamReader(System.in));
- }
- public FastReader(String s) throws FileNotFoundException {
- br = new BufferedReader(new FileReader(new File(s)));
- }
- String next() {
- while (st == null || !st.hasMoreElements()) {
- try {
- st = new StringTokenizer(br.readLine());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return st.nextToken();
- }
- int nextInt() {
- return Integer.parseInt(next());
- }
- int[] nextIntArray(int n) {
- int[] a = new int[n];
- for (int i = 0; i < n; i++)
- a[i] = nextInt();
- return a;
- }
- long nextLong() {
- return Long.parseLong(next());
- }
- long[] nextLongArray(int n) {
- long[] a = new long[n];
- for (int i = 0; i < n; i++)
- a[i] = nextLong();
- return a;
- }
- double nextDouble() {
- return Double.parseDouble(next());
- }
- double[] nextDoubleArray(int n) {
- double[] a = new double[n];
- for (int i = 0; i < n; i++)
- a[i] = nextDouble();
- return a;
- }
- String nextLine() {
- String str = "";
- try {
- str = br.readLine();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return str;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement