准备发blog时候才发现这题居然17年9月a过并且发过blog,BZOJ 2588 Spoj 10628 Count on a tree,当时称赞myc二十分钟a此题,但实际上的确几乎毫无思维难度,有板子的话五分钟A也是完全可能的。

没事,再来一次

题意:给定一棵树,n<=100000,询问m<=100000次,每次询问两个点之间的树链上第k大(第k小?)的值是多少,强制在线

看到k大值想到主席树,可以发现主席树由于这里是可持久化的权值线段树,有类似前缀和的性质

那么可以定义x点对应的主席树中的内容是从树根(开局时候随意指定,就用1)到x之间的所有点的权值

这样在读入询问时做一个加减法便可计算出答案 ans=kth(u+v-lca(u,v)-fa[lca(u,v)])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//by Richard
#include <bits/stdc++.h>
#include <bits/extc++.h>
#define mp make_pair
#define rep(x,y,z) for (int x=(y);(x)<=(z);(x)++)
#define per(x,y,z) for (int x=(y);(x)>=(z);(x)--)
#define lowbit(x) ((x)&(-(x)))
#ifdef DEBUG
#define debugdo(X) X
#define debugndo(X)
#define debugout(X) cout<<(#X)<<"="<<(X)<<endl
#else
#define debugdo(X)
#define debugndo(X) X
#define debugout(X)
#endif // debug
const int inf=0x3f3f3f3f;
using namespace std;
typedef long long LL;
typedef pair<int,int> pairs;
///////////////////////read5.1///////////////////////
template<typename T>
inline void read(T &x){char ch;x=0;bool flag=false;ch=getchar();while (ch>'9'||ch<'0') {if (ch=='-') flag=true;ch=getchar();}while ((ch<='9'&&ch>='0')){x=x*10+ch-'0';ch=getchar();}if (flag) x*=-1;}
template<typename T,typename U>
inline void read(T &x,U &y){read(x);read(y);}
template<typename T,typename U,typename V>
inline void read(T &x,U &y,V &z){read(x);read(y);read(z);}
////////////////variables&functions//////////////////
const int maxn=111111,maxvalue=100000;
int n,m,a[maxn];
map<int,int> ma;
struct node
{
node *l,*r;
int value;
node():l(0),r(0),value(0){}
node(node *ll,node *rr):l(ll),r(rr),value((ll?ll->value:0)+(rr?rr->value:0)){}
node(int vv):l(0),r(0),value(vv){}
};
node *root[maxn];
char memorypool[maxn*sizeof(node)*60];//1 char=1 byte
char *memorypoolptr=memorypool;
inline void* myalloc(size_t size)
{
return (memorypoolptr+=size)-size;
}
#define newnode new (myalloc(sizeof(node))) node
node* insert(node *x,int k,int L=0,int R=maxvalue)
{
if (L==R) return newnode(x?x->value+1:1);
int mid=(L+R)>>1;
if (k<=mid) return newnode(insert(x?x->l:0,k,L,mid),x?x->r:0);
else return newnode(x?x->l:0,insert(x?x->r:0,k,mid+1,R));
}
int kth(node *x,int k,int L=0,int R=maxvalue)
{
if (L==R) return L;
int mid=(L+R)>>1;
if (k<=(x->l?x->l->value:0)) return kth(x->l,k,L,mid);
else return kth(x->r,k-(x->l?x->l->value:0),mid+1,R);
}
int kth(node *x,node *y,int k,int L=0,int R=maxvalue)
{
if (L==R) return L;
if (!x) return kth(y,k,L,R);
int mid=(L+R)>>1,temp=(y->l?y->l->value:0)-(x->l?x->l->value:0);
if (k<=temp) return kth(x->l,y->l,k,L,mid);
else return kth(x->r,y->r,k-temp,mid+1,R);
}
int kth(node *x1,node *x2,node *y1,node *y2,int k,int L=0,int R=maxvalue)
{
if (L==R) return L;
int mid=(L+R)>>1,temp=(y1?(y1->l?y1->l->value:0):0)+(y2?(y2->l?y2->l->value:0):0)-(x1?(x1->l?x1->l->value:0):0)-(x2?(x2->l?x2->l->value:0):0);
if (k<=temp) return kth(x1?x1->l:0,x2?x2->l:0,y1?y1->l:0,y2?y2->l:0,k,L,mid);
else return kth(x1?x1->r:0,x2?x2->r:0,y1?y1->r:0,y2?y2->r:0,k-temp,mid+1,R);
}
struct GRAPH
{
int nxt[maxn<<1],first[maxn],to[maxn<<1],cnt;
int depth[maxn],f[maxn][30];
void addedge(int x,int y)
{
nxt[++cnt]=first[x];
first[x]=cnt;
to[cnt]=y;
}
void addedge2(int x,int y){addedge(x,y);addedge(y,x);}
void dfs(int x,int fa)
{
depth[x]=depth[fa]+1;
for (int i=1;(1<<i)<=depth[x];i++) f[x][i]=f[f[x][i-1]][i-1];
root[x]=insert(root[fa],a[x]);
for (int q=first[x];q;q=nxt[q]) if (to[q]!=fa) {f[to[q]][0]=x;dfs(to[q],x);}
}
int lca(int x,int y)
{
if (depth[x]<depth[y]) swap(x,y);
per(i,25,0)
{
if (depth[f[x][i]]>=depth[y]) x=f[x][i];
if (x==y) return x;
}
per(i,25,0) if (f[x][i]!=f[y][i]){x=f[x][i];y=f[y][i];}
return f[x][0];
}
}g;
int b[maxn];
int main()
{
read(n,m);
rep(i,1,n) read(a[i]);
rep(i,1,n) b[i]=a[i];
sort(b+1,b+n+1);
int nn=unique(b+1,b+n+1)-b;
rep(i,1,nn) ma[b[i]]=i;
rep(i,1,n) a[i]=ma[a[i]];
int x,y;
rep(i,1,n-1) {read(x,y);g.addedge2(x,y);}
g.dfs(1,0);
int lastans=0;
rep(i,1,m)
{
int u,v,k;
read(u,v,k);
u^=lastans;
int lca=g.lca(u,v);
int ans=b[kth(root[lca],root[g.f[lca][0]],root[u],root[v],k)];
printf("%d\n",lastans=ans);
}
return 0;
}