题目链接:https://codeforces.com/contest/1899/problem/G
离线每次查询。对于每一个查询的x,在搜索时将小区间合并到大区间里,然后直接二分查询出来
struct tdata{ int l,r,i; }; const int nn = 1e5+10; int a[nn],pos[nn]; vector<int> ve[nn]; vector<tdata> query[nn]; bool ans[nn]; vector<set<int>> st(nn); void dfs(int cur,int fa){ st[cur].insert(pos[cur]); for(auto c:ve[cur]){ if(c==fa) continue; dfs(c,cur); if(st[cur].size()<st[c].size()) swap(st[cur],st[c]); st[cur].insert(st[c].begin(),st[c].end()); } for(auto c:query[cur]){ int l = c.l,r=c.r,i=c.i; if(st[cur].lb(l)==st[cur].end()) continue; int L = *st[cur].lb(l); if(L<=r) ans[i] = true; } } void solve() { int n,q; cin>>n>>q; for(int i=1;i<=max(n,q);i++){ ans[i] = false; ve[i].clear();query[i].clear();st[i].clear(); } for(int i=1;i<n;i++){ int u,v; cin>>u>>v; ve[u].push_back(v); ve[v].push_back(u); } for(int i=1;i<=n;i++){ cin>>a[i]; pos[a[i]] = i; } for(int i=1;i<=q;i++){ int l,r,x; cin>>l>>r>>x; query[x].push_back({l,r,i}); } dfs(1,0); for(int i=1;i<=q;i++){ if(ans[i]) cyes; else cno; } cout<<endl; }