能过样例但是全都RE了,求调!
查看原帖
能过样例但是全都RE了,求调!
818633
younger18s楼主2023/5/25 22:21
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10 , M = 2 * N;

int n , m;
int e[M] , ne[M] , idx , h[N];
int a[N];
int root[N];
int dep[M] , fa[M][19];
int q[M];//模拟队列

vector<int>nums;

struct Node
{
	int l , r;
	int cnt;
}tr[N * 4 + N * 17];

void add(int a , int b)
{
	e[idx] = b , ne[idx] = h[a] , h[a] = idx ++;
	return;
} 

int build(int l , int r)
{
	int p = ++ idx;
	if(l == r)return p;
	int mid = l + r >> 1;
	tr[p].l = build(l , mid) , tr[p].r = build(mid + 1 , r);
	return p;
}

int insert(int p , int l , int r , int x)
{
	int q = ++ idx;
	tr[q] = tr[p];
	if(l == r)
	{
		tr[q].cnt ++;
		return q;
	}
	int mid = l + r >> 1;
	if(x <= mid)tr[q].l = insert(tr[p].l , l , mid , x);
	else tr[q].r = insert(tr[p].r , mid + 1 , r , x);
	tr[q].cnt = tr[tr[q].l].cnt + tr[tr[q].r].cnt;
	return q;
}

int find(int x)
{
	return lower_bound(nums.begin() , nums.end() , x) - nums.begin();
}

void dfs(int u , int father)
{
	for(int i = h[u] ; ~i ; i = ne[i])
	{
		int j = e[i];
		if(j == father)continue;
		root[j] = insert(root[u] , 0 , nums.size() - 1 , find(a[j]));
		dfs(j , u);
	}
	return;
}

// 最近公共祖先
void bfs(int root)
{
    memset(dep, 0x3f, sizeof dep);
    dep[0] = 0, dep[root] = 1;
    int hh = 0, tt = 0;
    q[0] = root;
    while (hh <= tt)
    {
        int t = q[hh ++ ];
        for (int i = h[t]; ~i; i = ne[i])
        {
            int j = e[i];
            if (dep[j] > dep[t] + 1)
            {
                dep[j] = dep[t] + 1;
                q[ ++ tt] = j;
                fa[j][0] = t;
                for (int k = 1; k <= 17; k ++ )
                    fa[j][k] = fa[fa[j][k - 1]][k - 1];
            }
        }
    }
    return;
}

int lca(int a , int b)
{
	if(dep[a] < dep[b])swap(a , b);
	for(int k = 17 ; k >= 0 ; k --)
	{
		if(dep[fa[a][k]] >= dep[b])
		{
			a = fa[a][k];
		}
	}
	if(a == b)
	{
		return a;
	}
	for(int k = 17 ; k >= 0; k --)
	{
		if(fa[a][k] != fa[b][k])
		{
			a = fa[a][k];
			b = fa[b][k];
		}
	}
	return fa[a][0];
}

//主席树查询(树上差分)

int query(int q , int p , int l , int r , int k , int u , int v)
{
	if(l == r)return r;
	int cnt = (tr[tr[q].l].cnt + tr[tr[p].l].cnt - tr[tr[u].l].cnt - tr[tr[v].l].cnt);
	int mid = l + r >> 1;
    if (k <= cnt) return query(tr[q].l, tr[p].l, l, mid, k , tr[u].l , tr[v].l);
    else return query(tr[q].r, tr[p].r, mid + 1, r, k - cnt , tr[u].r , tr[v].r);
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	memset(h , -1 , sizeof h);
	cin >> n >> m;
	for(int i = 1 ; i <= n ; i ++)
	{
		cin >> a[i];
		nums.push_back(a[i]);
	}
	sort(nums.begin() , nums.end());
	nums.erase(unique(nums.begin() , nums.end()) , nums.end());
	//离散化
	for(int i = 1 ; i < n ; i ++)
	{
		int a , b;
		cin >> a >> b;
		add(a , b);
		add(b , a);
	}
	root[0] = build(0 , nums.size() - 1);
	root[1] = insert(root[0] , 0 , nums.size() - 1 ,find(a[1]));
	dfs(1 , -1);
	bfs(1);
	int last = 0;
	while(m --)
	{
		int u , v , k;
		cin >> u >> v >> k;
		cout << nums[query(root[u ^ last] , root[v] , 0 , nums.size() - 1 , k , root[lca(u , v)] , root[fa[lca(u , v)][0]])] << '\n'; 
		last = nums[query(root[u ^ last], root[v] , 0 , nums.size() - 1 , k , root[lca(u , v)] , root[fa[lca(u , v)][0]])];
	}
	return 0;
}
2023/5/25 22:21
加载中...