列表

详情


NC214406. 武侍乐队

描述

“醒醒吧,武侍,咱们把这座城市,烧成灰。” 

夜之城内有n个场地可供演出,n-1条道路将他们连通,武侍有m个巡演计划。  

每场巡演计划预计从u出发,最终到v,在这个过程中,我们将武侍的表演风格记为s,从所周知,夜之城是一个鱼龙混杂的地方,所以每个场地附近的人对于音乐有着不同的见解,我们将其记为x,如果表演风格与当地人对音乐的见解差距太大,就可能不被当地居民所接受,银手认为这个差距可以记成。  

对于每一场巡演,银手都能预计到和表演风格相差最大的城市位置,为了避免影响评价,银手会选择跳过这座城市,一次巡演预计取得的正面评价是除了跳过城市外所有途径城市的x的异或和S。  

武侍出道时已累计了一定的好评,我们称其为w,对于每次巡演,你需要帮助武侍求出每次巡演最大的。其中

输入描述

第一行包含三个整数n,m,w,分别是夜之城可供演出的场地,武侍乐队的巡演次数,出道时的好评。  

接下来的n-1行,每行两个整数p,q,表示编号为p的场地与编号为q的场地之间有一条双向边,保证场地之间连通。  

接下来的一行有n个整数,表示这n个场地的人们对音乐的见解x。  

接下来m行,每行三个整数u,v,s,表示巡演起点,终点,与风格。

输出描述

对于每一次巡演,输出最大的

示例1

输入:

7 4 11
1 2
2 5
3 4
1 3
4 7
3 6
2 4 6 3 7 9 5
3 7 1
4 6 6
5 6 5
1 7 7

输出:

15
15
15
11

原站题解

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

C++(clang++11) 解法, 执行用时: 1178ms, 内存消耗: 116476K, 提交时间: 2021-04-06 13:34:39

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=2e5+10;
vector<int>v[N];
int x[N],f[N][20],dep[N],xo[N],cnt[32*N],rt[N],idx,tr[32*N][2];
void insert(int now,int pre,int val)
{
	for(int i=30;i>=0;i--)
	{
		bool v=val>>i&1;
		tr[now][v^1]=tr[pre][v^1];
		tr[now][v]=++idx;
		cnt[tr[now][v]]=cnt[tr[pre][v]]+1;
		now=tr[now][v];
		pre=tr[pre][v];
	}
}
void dfs(int u,int fa)
{
	f[u][0]=fa;
	dep[u]=dep[fa]+1;
	xo[u]=xo[fa]^x[u];
	for(int i=1;i<20;i++)f[u][i]=f[f[u][i-1]][i-1];
	for(auto i:v[u])
	{
		if(i==fa)continue;
		rt[i]=++idx;
		insert(rt[i],rt[u],x[i]);
		dfs(i,u);
	}
}
int lca(int x,int y)
{
	if(dep[x]<dep[y])swap(x,y);
	for(int i=19;i>=0;i--)
		if(dep[f[x][i]]>=dep[y])
			x=f[x][i];
			
	if(x==y)return x;
	
	for(int i=19;i>=0;i--)
		if(f[x][i]!=f[y][i])
			x=f[x][i],y=f[y][i];
	return f[x][0];
}
int query(int now,int pre,int val)
{
	int res=0;
	for(int i=30;i>=0;i--)
	{
		bool v=val>>i&1;
		if(cnt[tr[now][v^1]]>cnt[tr[pre][v^1]])
		{
			res+=1<<i;
			now=tr[now][v^1];
			pre=tr[pre][v^1];
		}
		else
		{
			now=tr[now][v];
			pre=tr[pre][v];
		}
	}
	return res;
}
int main()
{
	int n,m,w;
	scanf("%d%d%d",&n,&m,&w);
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		v[x].pb(y);
		v[y].pb(x);
	}
	for(int i=1;i<=n;i++)scanf("%d",&x[i]);
	dfs(1,0);
	while(m--)
	{
		int a,b,s;
		scanf("%d%d%d",&a,&b,&s);
		int p=lca(a,b);
		int ans=xo[a]^xo[b]^x[p];
		int ma=max({query(rt[b],rt[p],s),query(rt[a],rt[p],s),x[p]^s});
		ans=ans^ma^s;
		int res=0;
		for(int k=30;~k;--k)if(!(ans&(1<<k))&&res+(1<<k)<=w)res+=(1<<k);
		cout<<(ans^res)<<endl;
	}
	return 0;
}

上一题