# bzoj2588 Spoj 10628. Count on a tree

## 2588: Spoj 10628. Count on a tree

Time Limit: 12 Sec  Memory Limit: 128 MB
Submit: 8100  Solved: 2010
[Submit][Status][Discuss]

## Output

M行，表示每个询问的答案。最后一个询问不输出换行符

## Sample Input

8 5
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

2
8
9
105
7

N,M<=100000

## Source

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 100010;

int n,m,head[maxn],to[maxn * 2],nextt[maxn * 2],tot = 1,a[maxn],fa[maxn][21];
int b[maxn],cnt,num,root[maxn],lastans,deep[maxn];

struct node
{
int left,right,sum;
}e[maxn * 20];

{
to[tot] = y;
}

void update(int l,int r,int x,int &y,int v)
{
e[y = ++num] = e[x];
e[y].sum++;
if (l == r)
return;
int mid = (l + r) >> 1;
if (v <= mid)
update(l,mid,e[x].left,e[y].left,v);
else
update(mid + 1,r,e[x].right,e[y].right,v);
}

void dfs(int u,int faa,int dep)
{
fa[u][0] = faa;
deep[u] = dep;
int pos = lower_bound(b + 1,b + 1 + cnt,a[u]) - b;
update(1,cnt,root[faa],root[u],pos);
for (int i = head[u];i;i = nextt[i])
{
int v = to[i];
if (v == faa)
continue;
dfs(v,u,dep + 1);
}
}

int lca(int x,int y)
{
if (x == y)
return x;
if (deep[x] < deep[y])
swap(x,y);
for (int j = 19; j >= 0; j--)
if (deep[fa[x][j]] >= deep[y])
x = fa[x][j];
if (x == y)
return x;
for (int j = 19; j >= 0; j--)
if (fa[x][j] != fa[y][j])
x = fa[x][j],y = fa[y][j];
return fa[x][0];
}

int query(int l,int r,int a,int b,int c,int d,int k)
{
if (l == r)
return l;
int mid = (l + r) >> 1;
int temp = e[e[a].left].sum + e[e[b].left].sum - e[e[c].left].sum - e[e[d].left].sum;
if (k <= temp)
return query(l,mid,e[a].left,e[b].left,e[c].left,e[d].left,k);
else
return query(mid + 1,r,e[a].right,e[b].right,e[c].right,e[d].right,k - temp);
}

int main()
{
scanf("%d%d",&n,&m);
for (int i = 1; i <= n; i++)
scanf("%d",&a[i]);
memcpy(b,a,sizeof(a));
sort(b + 1,b + 1 + n);
cnt = unique(b + 1,b + 1 + n) - b - 1;
for (int i = 1; i < n; i++)
{
int x,y;
scanf("%d%d",&x,&y);
}
dfs(1,0,1);
for (int j = 1; j <= 19; j++)
for (int i = 1; i <= n; i++)
fa[i][j] = fa[fa[i][j - 1]][j - 1];
for (int i = 1; i <= m; i++)
{
int u,v,k;
scanf("%d%d%d",&u,&v,&k);
u ^= lastans;
int LCA = lca(u,v);
lastans = b[query(1,cnt,root[u],root[v],root[LCA],root[fa[LCA][0]],k)];
if (i != m)
printf("%d\n",lastans);
else
printf("%d",lastans);
}

return 0;
}

posted @ 2018-02-09 16:40  zbtrs  阅读(130)  评论(0编辑  收藏  举报