#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("O3,unroll-loops") //main
//#pragma GCC target("avx2") //cf...
//#pragma GCC target("sse4") //Quera
#define ll long long
typedef pair<int,int> pii;
typedef pair<int,pii> pip;
typedef pair<pii,int> ppi;
typedef pair<pii,pii> ppp;
#define f first
#define s second
#define lc 2*id
#define rc 2*id+1
#define mid (l+r)/2
#define all(x) x.begin(),x.end()
#define pb push_back
#define pp pop_back
#define unicorn(x) x.resize(unique(x.begin(),x.end())-x.begin())
#define dig(x,d) ((x&(1ll<<d)) > 0)
string pr(int* vv,int l,int r){for(int i=l;i<r;i++)cout<<vv[i]<<" ";return "";}
string pr( ll* vv,int l,int r){for(int i=l;i<r;i++)cout<<vv[i]<<" ";return "";}
string pr(vector<int> vv){for(auto i:vv)cout<<i<<" ";return "";}
string pr( vector<ll> vv){for(auto i:vv)cout<<i<<" ";return "";}
string pr(pii* vv,int l,int r){for(int i=l;i<r;i++)cout<<"( "<<vv[i].f<<","<<vv[i].s<<" ) ";return "";}
string pr(vector<pii> vv){for(auto i:vv)cout<<"( "<<i.f<<","<<i.s<<" ) ";return "";}
string pr(bool* vv,int l,int r){for(int i=l;i<r;i++)cout<<vv[i];return"";}
ostream& operator <<(ostream& out, pii x){out << "("<<x.f<<", "<<x.s<<") ";return out;}
const int L=2e5+10, lg=20;
const int inf=1e9+10;
int n,m;
bool mark[L];
vector<int> adj[L],P[L],tp;
int par[L][lg],h[L],st[L],fn[L],tr[L],tim;
int ind[L],F[L],S[L];
struct sagi{
int mx[L*4];
void reset(){
fill(mx+1,mx+L*4,0);
}
void update(int id,int l,int r,int ind,int x){
if(l+1 == r){
mx[id] = x;
return;
}
if(ind < mid)
update(lc,l,mid,ind,x);
else
update(rc,mid,r,ind,x);
mx[id] = max(mx[lc],mx[rc]);
}
int B(int id,int l,int r,int x){
if(mx[id] <= x)
return 0;
if(l+1 == r)
return l;
if(mx[rc] > x)
return B(rc,mid,r,x);
else
return B(lc,l,mid,x);
}
int F(int id,int l,int r,int l2,int r2,int x){
if(l2 >= r2) return 0;
if(l==l2 and r==r2)
return B(id,l,r,x);
int lr=0,rr=0;
if(r2 > mid)
rr = F(rc,mid,r,max(l2,mid),r2,x);
if(rr) return rr;
if(l2 < mid)
lr = F(lc,l,mid,l2,min(r2,mid),x);
return lr;
}
string prr(int id,int l,int r){
if(l+1 == r){
cout<<mx[id]<<" ";
return"";
}
prr(lc,l,mid);
prr(rc,mid,r);
return "";
}
}segp;
struct sagim{
struct node{
pii mn,mx;
node(){
mn = pii(inf,0);
mx = pii(0,0);
}
}t[L<<2];
void reset(){
for(int i=1;i<L*4;i++){
t[i].mn = pii(inf,0);
t[i].mx = pii(0,0);
}
}
node merge(node a,node b){
node ans;
ans.mn = min(a.mn, b.mn);
ans.mx = max(a.mx, b.mx);
return ans;
}
void update(int id,int l,int r,int ind,pii x){
if(l+1 == r){
t[id].mx = t[id].mn = x;
return;
}
if(ind < mid)
update(lc,l,mid,ind,x);
else
update(rc,mid,r,ind,x);
t[id] = merge(t[lc],t[rc]);
}
node get(int id,int l,int r,int l2,int r2){
if(l2 >= r2){
node ans;
return ans;
}
if(l==l2 and r==r2)
return t[id];
node ans;
if(l2 < mid)
ans = merge(ans,get(lc,l,mid,l2,min(r2,mid)));
if(r2 > mid)
ans = merge(ans,get(rc,mid,r,max(l2,mid),r2));
return ans;
}
string prr(int id,int l,int r){
if(l+1 == r){
cout<<t[id].mn<<" ";
return"";
}
prr(lc,l,mid);
prr(rc,mid,r);
return "";
}
}segb,segs;
void dfsT(int v){
tr[tim] = v;
st[v] = tim++;
for(auto u:adj[v]){
if(u != par[v][0]){
par[u][0] = v;
h[u] = h[v]+1;
dfsT(u);
}
}
fn[v] = tim;
}
int LCA(int u,int v){
if(h[u] > h[v])
swap(u,v);
for(int i=lg-1;i>=0;i--){
if(h[v] - (1<<i) >= h[u])
v = par[v][i];
}
if(u == v)
return u;
for(int i=lg-1;i>=0;i--){
if(par[u][i] != par[v][i]){
u = par[u][i];
v = par[v][i];
}
}
return par[u][0];
}
void dfs(int v){
mark[v] = 1;
/*
cout<<v<<" "<<S[v]<<" "<<F[v]<<endl;
cout<<"segb: "<<segb.prr(1,1,n+1)<<endl;
cout<<"segp: "<<segp.prr(1,1,n+1)<<endl;
cout<<"-------------------------------"<<endl;
*/
int lca = LCA(S[v],F[v]);
while(true){
int x = tr[segp.F(1,1,n+1,1,st[S[v]]+1,st[S[v]])];
if(x == 0 or h[x] < h[lca])
break;
segp.update(1,1,n+1,st[x],0);
if(!mark[ind[x]]){
//cout<<v<<" sp: "<<ind[x]<<endl;
dfs(ind[x]);
}
}
while(true){
int x = tr[segp.F(1,1,n+1,1,st[F[v]]+1,st[F[v]])];
if(x == 0 or h[x] < h[lca])
break;
segp.update(1,1,n+1,st[x],0);
if(!mark[ind[x]]){
//cout<<v<<" fp: "<<ind[x]<<endl;
dfs(ind[x]);
}
}
while(true){
pii x = segb.get(1,1,n+1,st[S[v]],fn[S[v]]).mn;
if(x.f >= st[S[v]])
break;
segb.update(1,1,n+1,max(st[S[x.s]],st[F[x.s]]),pii(inf,0));
if(!mark[x.s]){
//cout<<v<<" eb: "<<x.f<<" "<<x.s<<endl;
dfs(x.s);
}
}
while(true){
pii x = segs.get(1,1,n+1,st[S[v]],fn[S[v]]).mx;
if(x.f < fn[S[v]])
break;
segs.update(1,1,n+1,min(st[S[x.s]],st[F[x.s]]),pii(0,0));
if(!mark[x.s]){
//cout<<v<<" es: "<<x.f<<" "<<x.s<<endl;
dfs(x.s);
}
}
for(auto u:P[S[v]]){
if(!mark[u]){
dfs(u);
}
}
tp.pb(v);
}
void reset(){
segp.reset();
segs.reset();
segb.reset();
tp.clear();
tim=0;
for(int i=1;i<=n;i++){
ind[i] = mark[i] = 0;
P[i].clear();
adj[i].clear();
}
}
int main(){
//ofstream cout ("out.out");
//ifstream cin ("in.in");
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
cin>>t;
for(int gg=0;gg<t;gg++){
cin>>n;
reset();
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
adj[u].pb(v);
adj[v].pb(u);
}
h[0] = -1;
par[1][0] = h[1] = 0;
tim=1;
dfsT(1);
for(int j=1;j<lg;j++){
for(int i=1;i<=n;i++){
par[i][j] = par[par[i][j-1]][j-1];
}
}
cin>>m;
for(int i=1;i<=m;i++){
cin>>S[i]>>F[i];
ind[F[i]] = i;
P[LCA(S[i],F[i])].pb(i);
segp.update(1,1,n+1,st[F[i]],fn[F[i]]);
segs.update(1,1,n+1,min(st[F[i]],st[S[i]]),pii(max(st[F[i]],st[S[i]]),i));
segb.update(1,1,n+1,max(st[F[i]],st[S[i]]),pii(min(st[F[i]],st[S[i]]),i));
}
for(int i=1;i<=m;i++){
if(!mark[i]){
dfs(i);
}
}
reverse(all(tp));
if(tp.size() != m){
while(true){
int x = 1;
}
}
segp.reset();
for(int i=1;i<=m;i++){
segp.update(1,1,n+1,st[S[i]],fn[S[i]]);
}
bool ok = true;
for(auto i:tp){
int lca = LCA(S[i],F[i]);
//cout<<"segp: "<<segp.prr(1,1,n+1)<<endl;
//cout<<"lca: "<<lca<<endl;
segp.update(1,1,n+1,st[S[i]],0);
int x = tr[segp.F(1,1,n+1,1,st[S[i]]+1,st[S[i]])];
if(x != 0 and h[x] >= h[lca]){
//cout<<i<<" "<<x<<" bads "<<endl;
ok = false;
break;
}
x = tr[segp.F(1,1,n+1,1,st[F[i]]+1,st[F[i]])];
if(x != 0 and h[x] >= h[lca]){
//cout<<i<<" "<<x<<" badf "<<endl;
ok = false;
break;
}
segp.update(1,1,n+1,st[F[i]],fn[F[i]]);
}
if(ok)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
/*
cout<<"tr: "<<pr(tr,1,n+1)<<endl;
cout<<"st: "<<pr(st,1,n+1)<<endl;
cout<<"fn: "<<pr(fn,1,n+1)<<endl;
cout<<"tp: "<<pr(tp)<<endl;
*/
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |