CF1899G Unusual Entertainment 题解

分析

一眼树上启发式合并。

定义 xi 为节点 i 在序列 p 中的下标。则问题转化为:对于每组 l,r,k,询问以 k 为根的子树中是否有一个以上的节点,满足 lxjr

使用 set 存以 i 为根的子树中 xj 的有序排列。则对于每个 k=i 的询问,去合并之后的 set 中二分查找即可。树上启发式合并的话套版子就行了,只是多加了一个更新询问答案的过程而已。

注:模板题可以参照这道。但该模板题难度评级显然有问题。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
#define il inline
#define PII pair<int,pair<int,int>>
#define x first
#define y second

const int N=1e5+10;
int n,q;
int ne[N<<1],e[N<<1],h[N],idx;
struct node{
	set<int> st;
	vector<PII> Q;
	il int size(){return st.size();}
}sub[N];int x[N],id[N],cnt;
int ans[N];

il void add(int a,int b){ne[++idx]=h[a],e[idx]=b,h[a]=idx;}
il void dfs(int now,int fa){
	int mson=-1,msiz=0;
	id[now]=++cnt;
	for(re int i=h[now];i;i=ne[i]){
		int j=e[i];if(j==fa) continue;
		dfs(j,now);
		if(sub[id[j]].size()>msiz) msiz=sub[id[j]].size(),mson=j;
	}
	if(mson!=-1) id[now]=id[mson];
	for(re int i=h[now];i;i=ne[i]){
		int j=e[i];if(j==fa||j==mson) continue;
		for(auto s:sub[id[j]].st) sub[id[now]].st.insert(s);
		sub[id[j]].st.clear();
	}
	sub[id[now]].st.insert(x[now]);
	for(auto i:sub[now].Q){
		auto j=sub[id[now]].st.lower_bound(i.y.x);
		ans[i.x]=(j!=sub[id[now]].st.end()&&(*j)<=i.y.y);
	}
	return ;
}

il void solve(){
	cin>>n>>q;
	for(re int i=1;i<=n;++i) h[i]=ans[i]=x[i]=id[i]=0,sub[i].Q.clear(),sub[i].st.clear();
	idx=cnt=0;
	for(re int i=1,a,b;i<n;++i) cin>>a>>b,add(a,b),add(b,a);
	for(re int i=1,s;i<=n;++i) cin>>s,x[s]=i;
	for(re int i=1,l,r,x;i<=q;++i) cin>>l>>r>>x,sub[x].Q.push_back({i,{l,r}});
	dfs(1,0);
	for(re int i=1;i<=q;++i)
		if(ans[i]) cout<<"YES\n";
		else cout<<"NO\n";
	return ;
}

signed main(){
	int t;cin>>t;while(t--)
	solve();
	return 0;
}

posted @   harmis_yz  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示