列表

详情


NC237332. Tree Path

描述

There is a tree with n vertices and k weighted paths. The following operations are required to be supported:

A path (u,v) intersects with x if and only if x is one of the vertices in the shortest path from u to v (including u and v).

输入描述

The first line of input contains three positive integers n,k,m (), where m describes the number of operations.
The next n-1 lines each of which contains two positive integers a,b (), representing a tree edge.
The next k lines, each line contains three integers p,q,v (), representing a path with a weight of v. It is guaranteed that the path weights are different from each other.
The next m lines, the first integer of each line describes the type of the operation.
If , then follows an integer u, which describes the vertex of the query as .
last is the answer of the last query operation, and its initial value is 0. is the XOR symbol. It is guaranteed that , .

输出描述

For each query, output a line with an integer describing the smallest weight.
Output -1 if all weighted paths that have not been deleted intersect the queried vertex or all paths have been deleted.

示例1

输入:

5 2 4
1 2
1 3
3 4
3 5
1 3 1
3 5 2
1 3
1 -5
0
1 5

输出:

-1
1
2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 466ms, 内存消耗: 60972K, 提交时间: 2022-06-03 15:28:10

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
using pp=pair<int,int>;
int n,k,m,x,y,tot,ans,dep[N],a[N],d[N],lg[N],mi[N][20];
pp f[N][20];
vector<int>p[N];
struct dd
{
	int x,y,z;
	friend bool operator <(dd a,dd b)
	{
		return a.z<b.z;
	}
}q[N];
void dg(int x,int y)
{
	a[++tot]=x;
	d[x]=tot;
	dep[x]=dep[y]+1;
	for (auto t:p[x])
	if (t^y)
	{
		dg(t,x);
		a[++tot]=x;
	} 
}
int lca(int x,int y)
{
    if (d[x]>d[y]) swap(x,y);
    int k=lg[d[y]-d[x]+1];
    if (dep[mi[d[x]][k]]<dep[mi[d[y]-(1<<k)+1][k]]) return mi[d[x]][k];
    else return mi[d[y]-(1<<k)+1][k];
}
pp get(pp a,pp b)
{
	if (a==(pp){1e9,1e9}) return b; 
	if (a==(pp){-1,-1} || b==(pp){-1,-1}) return {-1,-1};
	int x[4];
	x[0]=lca(a.first,b.first);
	x[1]=lca(a.first,b.second);
	x[2]=lca(a.second,b.first);
	x[3]=lca(a.second,b.second);
	sort(x,x+4,[&](int a,int b){return dep[a]<dep[b];});
	if (x[2]^x[3]) return {x[2],x[3]};
	int p=lca(a.first,a.second);
	int q=lca(b.first,b.second);
	if (dep[x[2]]>=max(dep[p],dep[q])) return {x[2],x[2]};
	return {-1,-1};
}
bool in(int x,pp a)
{
	int z=lca(a.first,a.second);
	if (lca(x,z)!=z) return 0;
	return lca(x,a.first)==x || lca(x,a.second)==x;
}
int main()
{
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n>>k>>m;
	for (int i=1;i<n;i++)
	{
		cin>>x>>y;
		p[x].emplace_back(y);
		p[y].emplace_back(x);
	}
	dg(1,0);
	lg[0]=-1;
	for (int i=1;i<=tot;i++) lg[i]=lg[i>>1]+1;
	for (int i=1;i<=tot;i++) mi[i][0]=a[i];
	for (int j=1;j<18;j++)
		for (int i=1;i<=tot-(1<<j)+1;i++)
		mi[i][j]=dep[mi[i][j-1]]<dep[mi[i+(1<<j-1)][j-1]]?mi[i][j-1]:mi[i+(1<<j-1)][j-1];
	for (int i=1;i<=k;i++) cin>>q[i].x>>q[i].y>>q[i].z;
	sort(q+1,q+k+1);
	for (int i=1;i<=k;i++) f[i][0]={q[i].x,q[i].y};
	for (int j=1;j<18;j++)
		for (int i=1;i<=k-(1<<j)+1;i++)
		f[i][j]=get(f[i][j-1],f[i+(1<<j-1)][j-1]);
	int le=1;
	while (m--)
	{
		int tp;
		cin>>tp;
		if (tp==0) le++;
		else
		{
			cin>>x;
			x^=ans;
			pp w={1e9,1e9};
			int pos=le;
			for (int j=17;j>=0;j--)
			if (pos+(1<<j)-1<=k)
			{
				pp t=get(w,f[pos][j]);
				if (t!=(pp){-1,-1} && in(x,t))
				{
					w=t;
					pos+=1<<j; 
				}
			}
			if (pos<=k) ans=q[pos].z; else ans=-1; 
			cout<<ans<<'\n';
		}
	}
	return 0;
}

上一题