圣诞节到了,Wolfycz给Pigeon送了一棵圣诞树,这棵树有n个节点,n−1条边,节点上挂着一个个小礼物,每个礼物有一个价值,我们记i号节点上礼物的价值为Vi
Pigeon收到礼物之后非常开心,于是给Wolfycz扔了好几个问题:她每次指定两个节点x,y,并且问Wolfycz,x到y的路径上,价值第k小的礼物价值是多少
当然,Pigeon为了增加问题的难度,她会对每次询问的信息进行加密。具体而言,记上次的答案为LastAns(特别的,我们认为第一次询问的LastAns=0),那么Pigeon会给出x⊗LastAns,y⊗LastAns,k⊗LastAns的值(⊗为异或操作)
输入格式
第一行输入两个正整数n,m(1⩽n,m⩽2×105),表示树的节点数和Pigeon的询问次数
第二行输入n个正整数Vi(1⩽Vi⩽109),表示各个节点礼物的价值,保证各不相同
之后n−1行,每行两个正整数x,y(1⩽x,y⩽n),表示树的连边情况,即x,y之间有边相连,保证数据是一棵树
之后m行,每行三个正整数x,y,k,表示Pigeon给出的信息,记x′,y′,k′为解密后的信息,保证1⩽x′,y′⩽n,且k′⩽C,C表示x,y路径上的节点数(包含x,y两点)
输出格式
输出m行,每一行一个正整数,代表Pigeon询问的答案
输入样例
7 3
5 7 1 3 6 9 2
1 3
4 3
2 1
1 7
5 1
2 6
6 3 3
6 3 4
1 3 0
输出样例
7
5
9
提示
样例图如下所示:
第一次询问6(6⊗0),3(3⊗0)之间第3(3⊗0)小的,输出2号点的7
第二次询问1(6⊗7),4(3⊗7)之间第3(4⊗7)小的,输出1号点的5
第三次询问4(1⊗5),6(3⊗5)之间第5(0⊗5)小的,输出6号点的9
#include <istream>
#include <vector>
#include <queue>
#include <set>
#include <iostream>
using namespace std;
const int N = 2e5;
vector<int> e[N];
class myp
{
public:
bool operator()(int a, int b)const
{
return a <= b;
}
};
set<int, myp> s;//元素从小到大排序
bool vis[N];//是否已访问过该节点
int val[N],k;
int endv,las=0;
//目标节点 ; 最新值
void dfs(int u)
{
s.insert(val[u]);
if (u == endv)
{
int i = 0;
for (set<int, myp>::iterator it = s.begin(); it != s.end(); it++)
{
i++;
if (i == k)
{
las = *it;
cout << *it << endl;//输出第k个元素
break;
}
}
return;
}
for (vector<int>::iterator it = e[u].begin(); it != e[u].end(); it++)
{
int v = *it;
if (!vis[v])
{
vis[v] = true;
dfs(v);
vis[v] = false;
}
}
}
int n, m, x, y;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> val[i];
}
for (int i = 0; i < n-1; i++)
{
cin >> x >> y;
e[x].push_back(y);
e[y].push_back(x);
}
for (int i = 1; i <= m; i++)
{
cin >> x >> endv >> k;
x = x xor las;
endv = endv xor las;
k = k xor las;
memset(vis, false, sizeof vis);
s.clear();
vis[x] = true;
dfs(x);
}
}