2588: Spoj 10628. Count on a tree
Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 9280 Solved: 2421
[Submit][Status][Discuss]
Description
Input
Output
M行,表示每个询问的答案。最后一个询问不输出换行符
Sample Input
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2
Sample Output
8
9
105
7
HINT
1 //BZOJ 2588 可持久化线段树+LCA
2 #include<iostream>
3 #include<cstdio>
4 #include<cstring>
5 #include<algorithm>
6 #include<bitset>
7 #include<cassert>
8 #include<cctype>
9 #include<cmath>
10 #include<cstdlib>
11 #include<ctime>
12 #include<deque>
13 #include<iomanip>
14 #include<list>
15 #include<map>
16 #include<queue>
17 #include<set>
18 #include<stack>
19 #include<vector>
20 using namespace std;
21 typedef long long ll;
22
23 const double PI=acos(-1.0);
24 const double eps=1e-6;
25 const ll mod=1e9+7;
26 const int inf=0x3f3f3f3f;
27 const int maxn=1e5+10;
28 const int maxm=100+10;
29 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
30 #define lson l,m
31 #define rson m+1,r
32
33 int ans,tot,cnt,lca;
34 int n,d,q;
35 int a[maxn],b[maxn],h[maxn],L[maxn<<5],R[maxn<<5];
36 int to[maxn<<5],head[maxn],Next[maxn<<5];//存图
37 int sum[maxn<<5],root[maxn],dep[maxn];
38 int fa[maxn][20];
39
40 void add(int x,int y)//存图
41 {
42 tot++;
43 Next[tot]=head[x];
44 head[x]=tot;
45 to[tot]=y;
46 }
47
48 int LCA(int x,int y)
49 {
50 if(dep[x]<dep[y]) swap(x,y);
51 for(int i=0;i<=19;i++) if(((dep[x]-dep[y])&(1<<i))!=0) x=fa[x][i];//不知道为什么我注释掉的那种写法为什么不对。。。
52 //for(int i=0;i<=19;i++) if(dep[x]==dep[y]-(1<<i)) x=fa[x][i];
53 if(x==y) return x;
54 for(int i=19;i>=0;i--){
55 if(fa[x][i]!=fa[y][i]){
56 x=fa[x][i];
57 y=fa[y][i];
58 }
59 }
60 return fa[x][0];
61 }
62
63 void update(int pre,int &rt,int l,int r,int k)
64 {
65 rt=++cnt;sum[rt]=sum[pre]+1;
66 L[rt]=L[pre];R[rt]=R[pre];
67 if(l==r){
68 return ;
69 }
70
71 int m=(l+r)>>1;
72 if(k<=m) update(L[pre],L[rt],lson,k);
73 else update(R[pre],R[rt],rson,k);
74 }
75
76 int query(int x,int y,int lca,int fa,int l,int r,int k)
77 {
78 if(l==r){
79 return h[l];
80 }
81
82 int m=(l+r)>>1;
83 int now=sum[L[x]]+sum[L[y]]-sum[L[lca]]-sum[L[fa]];
84 if(now>=k) return query(L[x],L[y],L[lca],L[fa],lson,k);
85 else return query(R[x],R[y],R[lca],R[fa],rson,k-now);
86 }
87
88 void dfs(int x,int fath)//按照dfs进行更新
89 {
90 dep[x]=dep[fath]+1;
91 int k=lower_bound(b+1,b+1+d,a[x])-b;
92 h[k]=a[x];
93 update(root[fath],root[x],1,n,k);
94 for(int i=1;i<=19;i++){
95 fa[x][i]=fa[fa[x][i-1]][i-1];
96 }
97 for(int i=head[x];i;i=Next[i]){
98 if(to[i]!=fath){
99 fa[to[i]][0]=x;
100 dfs(to[i],x);
101 }
102 }
103 }
104
105 int main()
106 {
107 scanf("%d%d",&n,&q);
108 for(int i=1;i<=n;i++){
109 scanf("%d",&a[i]);
110 b[i]=a[i];
111 }
112 sort(b+1,b+1+n);
113 d=unique(b+1,b+1+n)-(b+1);//去重建立权值线段树
114 for(int i=1;i<n;i++){
115 int x,y;
116 scanf("%d%d",&x,&y);
117 add(x,y);
118 add(y,x);
119 }
120 dfs(1,0);
121 while(q--){
122 int x,y,k;
123 scanf("%d%d%d",&x,&y,&k);
124 x=x^ans;
125 lca=LCA(x,y);
126 ans=query(root[x],root[y],root[lca],root[fa[lca][0]],1,n,k);//按照LCA,从x到lca,然后从lca到y,去掉lca的爸爸。
127 printf("%d\n",ans);
128 }
129 }