Submission #1246335

#TimeUsernameProblemLanguageResultExecution timeMemory
1246335damoonJail (JOI22_jail)C++20
26 / 100
2263 ms91496 KiB
#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(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(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]]+1)];
        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]]+1)];
        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);
        }
        par[1][0] = 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));

        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]]+1)];
            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]]+1)];
            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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...