【Vijos】lxhgww的奇思妙想

题面

题解

求$k$级祖先孙子

为什么要用长链剖分啊???

倍增并没有慢多少。。。

其实是我不会

长链剖分做这道题还是看这位巨佬的吧。

代码

#include<bits/stdc++.h>
#define RG register
#define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
#define clear(x, y) memset(x, y, sizeof(x));
using namespace std;

inline int read()
{
	int data = 0, w = 1;
	char ch = getchar();
	while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
	if(ch == '-') w = -1, ch = getchar();
	while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
	return data*w;
}

const int maxn(300010), Log(21);
struct edge { int next, to; } e[maxn << 1];
int head[maxn], e_num, n, m, f[maxn][Log];
inline void add_edge(int from, int to)
{
	e[++e_num] = (edge) {head[from], to}; head[from] = e_num;
	e[++e_num] = (edge) {head[to], from}; head[to]   = e_num;
}

void dfs(int x)
{
	for(RG int i = 1; i <= 20; i++) f[x][i] = f[f[x][i - 1]][i - 1];
	for(RG int i = head[x]; i; i = e[i].next)
	{
		int to = e[i].to;
		if(to == f[x][0]) continue;
		f[to][0] = x; dfs(to);
	}
}

inline int Query(int x, int k)
{
	for(RG int i = 20; ~i; i--) if((k >> i) & 1) x = f[x][i];
	return x;
}

int main()
{
	n = read();
	for(RG int i = 1; i < n; i++) add_edge(read(), read());
	m = read(); int lastans = 0; dfs(1);
	while(m--)
	{
		int a = read() ^ lastans, b = read() ^ lastans;
		printf("%d\n", lastans = Query(a, b));
	}
	return 0;
}
posted @ 2019-01-06 19:29  xgzc  阅读(258)  评论(4编辑  收藏  举报