Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #define ll long long
- #define pb push_back
- #define f first
- #define s second
- #define mp make_pair
- using namespace std;
- const int MAXN = 1e5 + 10;
- const int INF = 1e9 + 7;
- int p[MAXN], tin[MAXN], tout[MAXN];
- vector <int> g[MAXN];
- bool was[MAXN];
- bool upper(int a, int b){
- return (tin[a] < tin[b] && tout[a] > tout[b]);
- }
- int timer;
- void dfs(int v){
- was[v] = 1;
- tin[v] = ++timer;
- for (int to : g[v]){
- if (!was[to]){
- dfs(to);
- }
- }
- tout[v] = ++timer;
- }
- vector <pair <int, int> > t[4 * MAXN];
- vector <pair <int, int>> combine(int v){
- vector <pair <int, int> > new_v;
- int it1 = 0;
- int it2 = 0;
- int len1 = t[v << 1].size();
- int len2 = t[(v << 1) | 1].size();
- while (it1 < len1 && it2 < len2){
- if (t[v << 1][it1].first > t[(v << 1) | 1][it2].first){
- new_v.pb(t[v << 1][it1]);
- it1++;
- if (new_v.size() > 1){
- int len = new_v.size();
- new_v[len - 1].s = min(new_v[len - 1].s, new_v[len - 2].s);
- }
- }
- else{
- new_v.pb(t[(v << 1) | 1][it2]);
- it2++;
- if (new_v.size() > 1){
- int len = new_v.size();
- new_v[len - 1].s = min(new_v[len - 1].s, new_v[len - 2].s);
- }
- }
- }
- while (it1 < len1){
- new_v.pb(t[v << 1][it1]);
- it1++;
- if (new_v.size() > 1){
- int len = new_v.size();
- new_v[len - 1].s = min(new_v[len - 1].s, new_v[len - 2].s);
- }
- }
- while (it2 < len2){
- new_v.pb(t[(v << 1) | 1][it2]);
- it2++;
- if (new_v.size() > 1){
- int len = new_v.size();
- new_v[len - 1].s = min(new_v[len - 1].s, new_v[len - 2].s);
- }
- }
- return new_v;
- }
- void build(int v, int tl, int tr){
- if (tl > tr)
- return;
- if (tl == tr){
- t[v].clear();
- t[v].push_back({tin[p[tl]], tout[p[tl]]});
- return;
- }
- int tm = (tl + tr) >> 1;
- build(v << 1, tl, tm);
- build((v << 1) | 1, tm + 1, tr);
- t[v] = combine(v);
- }
- int get(int v, int tl, int tr, int l, int r, int x){
- if (l > r){
- return INF;
- }
- if (tl == l && tr == r){
- int pos = t[v].size();
- int left = 0;
- int right = t[v].size() - 1;
- while (left <= right){
- int mid = (left + right) / 2;
- if (t[v][mid].first >= tin[x]){
- pos = mid;
- left = mid + 1;
- }
- else{
- right = mid - 1;
- }
- }
- if (pos == t[v].size()){
- return INF;
- }
- return (t[v][pos].second);
- }
- int tm = (tl + tr) >> 1;
- return min(get(v << 1, tl, tm, l, min(r, tm), x),
- get((v << 1) | 1, tm + 1, tr, max(l, tm + 1), r, x));
- }
- void solve() {
- int n, q;
- cin >> n >> q;
- for (int i = 1; i <= n; i++){
- g[i].clear();
- was[i] = 0;
- }
- for (int i = 1; i < n; i++){
- int x, y;
- cin >> x >> y;
- g[x].pb(y);
- g[y].pb(x);
- }
- for (int i = 1; i <= n; i++){
- cin >> p[i];
- }
- timer = 0;
- dfs(1);
- build(1, 1, n);
- /*
- for (auto [ti, to] : t[2]){
- cout << "# " << ti << ' ' << to << endl;
- }
- for (int i = 1; i <= 5; i++){
- cout << "!!! " << t[i].size() << ' ';
- }
- cout << endl;*/
- for (int i = 1; i <= q; i++){
- int l, r, x;
- cin >> l >> r >> x;
- if (get(1, 1, n, l, r, x) <= tout[x]){
- cout << "YES\n";
- }
- else{
- cout << "NO\n";
- }
- }
- }
- int main(){
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- int ttt = 1;
- cin >> ttt;
- while (ttt--){
- solve();
- }
- }
- /*
- 1
- 3 5
- 1 2
- 2 3
- 1 2 3
- 1 2 2
- 1 2 3
- 2 3 1
- 1 2 3
- 2 3 3
- */
Advertisement
Add Comment
Please, Sign In to add comment