XORTREE
题号:NC200191
时间限制:C/C++/Rust/Pascal 1秒,其他语言2秒
空间限制:C/C++/Rust/Pascal 256 M,其他语言512 M
64bit IO Format: %lld

题目描述

    给出一颗个结点条边的带权树,第个结点的权值为 
    定义点到点的路径的长度为点到点的最短路径上的所有结点的权值的异或和。
    单独一个点不算做路径。
    现在要求你维护个操作:
          将点的权值修改为
        求点到点之间的所有子路径的长度的异或和

输入描述:

第一行两个整数
第二行n个整数表示
接下来n-1行每行两个整数表示之间有一条边
接下来q行每行三个整数表示一个查询,数据保证对于查询,满足

输出描述:

对于每个查询输出一行一个整数表示答案
示例1

输入

复制
5 3
1 2 3 4 5
1 2
2 3
3 4
4 5
2 1 5
1 2 8
2 1 5

输出

复制
6
12

说明

{f(u,v)}表示点{u}到点{v}最短路径上所有结点的权值的异或和,那么第一个查询的答案为:
{f(1,2)\bigoplus f(1,3)\bigoplus f(1,4)\bigoplus f(1,5)\bigoplus f(2,3)\bigoplus f(2,4)\bigoplus f(2,5)\bigoplus f(3,4)\bigoplus f(3,5)\bigoplus f(4,5)=6}
其中{f(1,4)=1\bigoplus 2\bigoplus 3\bigoplus 4,f(2,5)=2\bigoplus 3\bigoplus 4\bigoplus 5},其它的类似。

备注:

1<=u,v<=n,q<=2e5
1<=ai,x<=1e9
建议使用快读
int read()
{
    int x=0;
    char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=getchar();
    return x;
}