Submission #1168455

#TimeUsernameProblemLanguageResultExecution timeMemory
1168455lampoopppJail (JOI22_jail)C++20
100 / 100
813 ms116872 KiB
#include <bits/stdc++.h>
using namespace std;

const int N=2e5;
vector<int> adj[N+1];
int vis[N+1],chi[N+1];
int pa[N+1],n,m,h[N+1];
int l[N+1], r[N+1];
int up[N+1][20];
int vis2[9*N+1];
int id[9*N+1];

vector<int> adj2[9*N+1];

void build(int x, int low, int hi, int n)
{
    if(low==hi) return;
    int mid=low+hi>>1;
    adj2[x].push_back(x*2);
    adj2[x].push_back(x*2+1);
    adj2[4*n+x*2].push_back(4*n+x);
    adj2[4*n+x*2+1].push_back(4*n+x);
    build(x*2,low,mid,n);
    build(x*2+1,mid+1,hi,n);
}

void dfs(int u)
{
    chi[u]=1;
    vis[u]=1;
    for(int v : adj[u])
    {
        if(vis[v]) continue;
        pa[v]=u;
        h[v]=h[u]+1;
        up[v][0]=u;
        for(int i=1;i<20;++i) up[v][i] = up[up[v][i-1]][i-1];
        dfs(v);
        chi[u]+=chi[v];
    }
    //cout << u << " "
}

int chead[N+1], cid[N+1], pos[N+1], ch=1, tme=0;

void hld(int u)
{
    cid[u]=ch;
    pos[u]=++tme;
    int mx=0;
    int k;
    for(int v : adj[u])
    {
        if(v==pa[u]) continue;
        if(mx<chi[v])
        {
            mx=chi[v];
            k=v;
        }
    }
    if(mx==0) return;
    hld(k);
    for(int v : adj[u])
    {
        if(v==k || v==pa[u]) continue;
        ch++;
        chead[ch]=v;
        hld(v);
    }
}

int lca(int u, int v)
{
    if(h[u]<h[v]) swap(u,v);
    int k = h[u]-h[v];
    for(int i=0;i<20;++i)
    {
        if(k>>i&1) u = up[u][i];
    }
    if(u==v) return u;
    k = __lg(h[u]);
    for(;k>=0;--k)
    {
        if(up[u][k]!=up[v][k])
        {
            u=up[u][k];
            v=up[v][k];
        }
    }
    return up[u][0];
}

int findpos(int x, int low, int hi, int i)
{
    if(low==hi) return x;
    int mid=low+hi>>1;
    if(i<=mid) return findpos(x*2,low,mid,i);
    return findpos(x*2+1,mid+1,hi,i);
}

void update(int x, int low, int hi, int i, int j, int k, int z)
{
    if(low > hi || low > j || hi<i) return;
    if(low>=i && hi<=j)
    {
        if(z==1) adj2[k+8*n].push_back(id[x]); // i->t
        else
        {
            //cout << "DM" << low << " " << hi << " " << id[x+4*n] << '\n';
            adj2[id[x+4*n]].push_back(k+8*n); //s->i
        }
        return;
    }
    int mid=low+hi>>1;
    update(x*2,low,mid,i,j,k,z);
    update(x*2+1,mid+1,hi,i,j,k,z);
}

void connecttree(int u, int v, int i, int type)
{
    if(h[v]<h[u]) return;
    while(cid[u]!=cid[v])
    {
        update(1,1,n,pos[chead[cid[v]]],pos[v],i,type);
        v=up[chead[cid[v]]][0];
    }
    update(1,1,n,pos[u],pos[v],i,type);
}

bool anc=false;

void sol(int u)
{
  //  cout << u << " ";
    vis2[u]=1;
    for(int x : adj2[u])
    {
        int v = id[x];
        if(vis2[v]==2) continue;
        if(vis2[v]==1)
        {
            anc=true;
            return;
        }
        sol(v);
        if(anc) return;
    }
    vis2[u]=2;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        ch=1;
        tme=0;
        cin >> n;
        for(int i=1;i<=n;++i) adj[i].clear();
        for(int i=1;i<=9*n;++i) adj2[i].clear();
        fill(vis+1,vis+n+1,0);
        fill(vis2+1,vis2+9*n+1,0);
        for(int i=1;i<n;++i)
        {
            int u,v;
            cin >> u >> v;
            adj[u].push_back(v);
            adj[v].push_back(u);
        }
        build(1,1,n,n);
        dfs(1);
        hld(1);
//        for(int i=1;i<=n;++i) cout << pos[i] << " ";
//        cout << '\n';
        cin >> m;
        for(int i=1;i<=9*n;++i) id[i]=i;
        for(int i=1;i<=m;++i)
        {
            cin >> l[i] >> r[i];
            int a = findpos(1,1,n,pos[l[i]]);
            int b = findpos(1,1,n,pos[r[i]]);
            id[a+4*n]=i+8*n;
            id[b]=i+8*n;
            for(int v : adj2[b]) adj2[i+8*n].push_back(v);
            for(int v : adj2[a+4*n]) adj2[i+8*n].push_back(v);
    //        adj2[a+4*n].push_back(i+8*n);
    //        adj2[b].push_back(i+8*n);
            int x = lca(l[i],r[i]);
            int u=l[i];
            int v=r[i];
            if(x!=u && x!=v)
            {
                int tmp = v;
                int k = h[v]-h[x]-1;
                for(int i=0;i<20;++i)
                    if(k>>i&1) tmp=up[tmp][i];
                connecttree(x,u,i,1);
                connecttree(tmp,up[v][0],i,1);

                connecttree(x,up[u][0],i,2);
                connecttree(tmp,v,i,2);
            }
            else if(x==u)
            {
                int k = h[v]-h[u]-1;
                u=v;
                for(int i=0;i<20;++i)
                    if(k>>i&1) u=up[u][i];
                connecttree(x,up[v][0],i,1);
                connecttree(u,v,i,2);
            }
            else if(x==v)
            {
                int k = h[u]-h[v]-1;
                v=u;
                for(int i=0;i<20;++i)
                    if(k>>i&1) v=up[v][i];
                connecttree(v,u,i,1);
                connecttree(x,up[u][0],i,2);
            }
        }
        fill(vis+1,vis+9*n+1,0);
        anc=false;
//        for(int i=1;i<=9*n;++i)
//        {
//            for(int v : adj2[id[i]]) cout << id[i] << " " << id[v] << '\n';
//        }
        sol(1);
        if(anc) cout << "No\n";
        else cout << "Yes\n";
    }
}
#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...