主席树RE了,蒟蒻在线求助
查看原帖
主席树RE了,蒟蒻在线求助
59317
legend_life楼主2020/8/21 21:57
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define mp make_pair
#define pb push_back
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;

int read()
{
	char c = getchar(); int flag = 1, ans = 0;
	while (c < '0' || c > '9') {if (c == '-') flag = -flag; c = getchar();}
	while (c >= '0' && c <= '9') {ans = ans * 10 + c - '0'; c = getchar();}
	return ans * flag;
}

const ll INF = 1e16;
const int MAXN = 100010;
const int MOD = 998244353;
int a[MAXN], b[MAXN], head[MAXN], rt[MAXN], lc[MAXN * 20], rc[MAXN * 20], val[MAXN * 20], fa[MAXN][20], dep[MAXN], lg2[MAXN];
int n, m, q, cnt, tot;

struct Edge
{
	int to;
	int nxt;
}e[MAXN << 1];

void AddEdge (int from, int to)
{
	e[++ cnt].to = to;
	e[cnt].nxt = head[from];
	head[from] = cnt;
}

void build_tree (int &o, int l, int r)
{
	o = ++ tot;
	if (l == r)	return;
	int mid = (l + r) >> 1;
	build_tree (lc[o], l, mid);
	build_tree (rc[o], mid + 1, r);
}

void modify (int &o, int pre, int l, int r, int x)
{
	o = ++ tot;
	lc[o] = lc[pre], rc[o] = rc[pre], val[o] = val[pre] + 1;
	if (l == r)	return;
	int mid = (l + r) >> 1;
	if (x <= mid)	modify (lc[o], lc[pre], l, mid, x);
	else	modify (rc[o], rc[pre], mid + 1, r, x);
}

int query (int a, int b, int c, int d, int l, int r, int k)
{
	if (l == r)	return l;
	int cur = val[lc[a]] + val[lc[b]] - val[lc[c]] - val[lc[d]], mid = (l + r) >> 1;
	if (k <= cur)
		return query (lc[a], lc[b], lc[c], lc[d], l, mid, k);
	else
		return query (rc[a], rc[b], rc[c], rc[d], mid + 1, r, k - cur);
}

void dfs (int u, int f)
{
	dep[u] = dep[f] + 1;
	fa[u][0] = f;
	modify (rt[u], rt[f], 1, m, a[u]);
	for (int i = head[u]; i; i = e[i].nxt)
	{
		int v = e[i].to;
		if (v == f)
			continue;
		dfs (v, u);
	}
}

void init()
{
	dfs (1, 0);
	for (int i = 2; i <= n; ++ i)
		lg2[i] = lg2[i >> 1] + 1;
	for (int i = 1; i <= 20; ++ i)
		for (int j = 1; j <= n; ++ j)
			fa[j][i] = fa[fa[j][i - 1]][i - 1];
}

int lca (int x, int y)
{
	if (dep[x] < dep[y])
		swap (x, y);
	while (dep[x] > dep[y])
		x = fa[x][lg2[dep[x] - dep[y]]];
	if (x == y)
		return x;
	for (int i = 18; i >= 0; -- i)
		if (fa[x][i] != fa[y][i])
			x = fa[x][i], y = fa[y][i];
	return fa[x][0];
}

int main()
{
	n = read(), q = read();
	for (int i = 1; i <= n; ++ i)
		a[i] = b[i] = read();
	sort (b + 1, b + n + 1);
	m = unique (b + 1, b + n + 1) - b - 1;
	build_tree (rt[0], 1, m);
	for (int i = 1; i <= n; ++ i)
		a[i] = lower_bound (b + 1, b + m + 1, a[i]) - b;
	
	for (int i = 1; i < n; ++ i)
	{
		int u = read(), v = read();
		AddEdge (u, v);
		AddEdge (v, u);
	}
	init();
	int ans = 0;
	for (int i = 1; i <= q; ++ i)
	{
		int u = read() ^ ans, v = read(), k = read(), LCA = lca (u, v);
		ans = b[query (rt[u], rt[v], rt[LCA], rt[fa[LCA][0]], 1, m, k)];
		printf ("%d\n", ans);
	}
	return 0;
}

我不知道是ans求错了还是数组越界了,恳请各位带师帮忙,谢谢了

2020/8/21 21:57
加载中...