Submission #993814

#TimeUsernameProblemLanguageResultExecution timeMemory
993814snpmrnhlolJail (JOI22_jail)C++17
100 / 100
744 ms86548 KiB
#include<bits/stdc++.h>
using namespace std;
const int N = 12e4;
const int S = 5*N;
const int logN = 20;
int t;
vector <int> e[N];
vector <int> e2[S];
int deg[S];
int n,m;
int ls[S],rs[S];
queue <int> q;
int cnt = 0;
int root1;
int root2;
int sub[N];
int dpth[N];
int cnt2 = 0;
int st[N],st2[N];
int starts[N],endz[N];
int top[N];
int p1[N],p2[N];
int su[N],sw[N];
int pr[N];
int rmq[N][logN];
void build1(int l = 0,int r = n - 1,int node = 0){
    if(l != r){
        int mij = (l + r)/2;
        if(l != mij)ls[node] = cnt++;
        else ls[node] = p1[mij];
        if(mij + 1 != r)rs[node] = cnt++;
        else rs[node] = p1[mij + 1];
        //cout<<"addedge:"<<node<<' '<<ls[node]<<'\n';
        //cout<<"addedge:"<<node<<' '<<rs[node]<<'\n';
        e2[node].push_back(ls[node]);
        e2[node].push_back(rs[node]);
        build1(l,mij,ls[node]);
        build1(mij + 1,r,rs[node]);
    }
}
void build2(int l = 0,int r = n - 1,int node = 0){
    if(l != r){
        int mij = (l + r)/2;
        if(l != mij)ls[node] = cnt++;
        else ls[node] = p2[mij];
        if(mij + 1 != r)rs[node] = cnt++;
        else rs[node] = p2[mij + 1];
        //cout<<"addedge:"<<ls[node]<<' '<<node<<'\n';
        //cout<<"addedge:"<<rs[node]<<' '<<node<<'\n';
        e2[ls[node]].push_back(node);
        e2[rs[node]].push_back(node);
        build2(l,mij,ls[node]);
        build2(mij + 1,r,rs[node]);
    }
}
void dfs(int node, int p){
    pr[node] = p;
    sub[node] = 1;
    if(p == -1)dpth[node] = 0;
    else dpth[node] = dpth[p] + 1;
    for(auto i:e[node]){
        if(i == p)continue;
        dfs(i, node);
        sub[node]+=sub[i];
    }
    int mxid = -1;
    for(int i = 0;i < e[node].size();i++){
        if(e[node][i] == p)continue;
        if(mxid == -1 || sub[e[node][mxid]] < sub[e[node][i]]){
            mxid = i;
        }
    }
    if(mxid != -1){
        swap(e[node][mxid],e[node][0]);
    }
    for(int i = 0;i < e[node].size();i++){
        if(e[node][i] == p){
            swap(e[node][i],e[node].back());
            e[node].pop_back();
            break;
        }
    }
}
int last[N],first[N];
int laen[N],firen[N];
int rp1[N],rp2[N];
int cnt3 = 0,cnt4 = 0;
void dfs2(int node, int p){
    //cout<<"dfs:"<<node<<' '<<p<<'\n';
    st[node] = cnt2++;
    st2[cnt2 - 1] = node;
    bool ok = 0;
    if(starts[node] != -1){
        //cout<<"assignment:"<<node<<'\n';
        rp1[node] = cnt3++;
        p1[cnt3 - 1] = starts[node];
    }
    if(endz[node] != -1){
        rp2[node] = cnt4++;
        p2[cnt4 - 1] = endz[node];
    }
    if(starts[node] != -1){
        first[node] = node;
    }else if(top[node] == node){
        first[node] = -1;
    }else{
        first[node] = first[p];
    }
    //cout<<node<<' '<<first[node]<<'\n';
    if(endz[node] != -1){
        firen[node] = node;
    }else if(top[node] == node){
        firen[node] = -1;
    }else{
        firen[node] = firen[p];
    }
    for(auto i:e[node]){
        if(i == p)continue;
        if(!ok){
            top[i] = top[node];
        }else{
            top[i] = i;
        }
        dfs2(i, node);
        ok = 1;
    }
    if(starts[node] != -1){
        last[node] = node;
    }else if(!e[node].empty()){
        last[node] = last[e[node][0]];
    }else{
        last[node] = -1;
    }
    if(endz[node] != -1){
        laen[node] = node;
    }else if(!e[node].empty()){
        laen[node] = laen[e[node][0]];
    }else{
        laen[node] = -1;
    }
}
void updstart(int ql,int qr,int id,int l = 0,int r = m - 1,int node = root1){
    assert(ql <= qr);
    if(ql <= l && r <= qr){
        e2[id].push_back(node);
        //cout<<"addedge:"<<id<<' '<<node<<'\n';
    }else{
        int mij = (l + r)/2;
        if(qr <= mij){
            updstart(ql,qr,id,l,mij,ls[node]);
        }else if(mij + 1 <= ql){
            updstart(ql,qr,id,mij + 1,r,rs[node]);
        }else{
            updstart(ql,qr,id,l,mij,ls[node]);
            updstart(ql,qr,id,mij + 1,r,rs[node]);
        }
    }
}
void updends(int ql,int qr,int id,int l = 0,int r = m - 1,int node = root2){
    assert(ql <= qr);
    if(ql <= l && r <= qr){
        e2[node].push_back(id);
        //cout<<"addedge:"<<node<<' '<<id<<'\n';
    }else{
        int mij = (l + r)/2;
        if(qr <= mij){
            updends(ql,qr,id,l,mij,ls[node]);
        }else if(mij + 1 <= ql){
            updends(ql,qr,id,mij + 1,r,rs[node]);
        }else{
            updends(ql,qr,id,l,mij,ls[node]);
            updends(ql,qr,id,mij + 1,r,rs[node]);
        }
    }
}
int prog(int u,int w){
    int df = dpth[w] - dpth[u] - 1;
    if(df < 0)return pr[u];
    for(int i = logN - 1;i >= 0;i--){
        if(df>>i&1){
            df-=(1<<i);
            w = rmq[w][i];
        }
    }
    if(pr[w] == u)return w;
    return pr[u];
}
void addstarts(int u,int w,int id){
    u = prog(u,w);
    while(top[u] != top[w]){
        if(dpth[top[u]] > dpth[top[w]])swap(u,w);
        //cout<<"fire:"<<u<<' '<<w<<' '<<id<<' '<<first[w]<<' '<<last[top[w]]<<' '<<rp1[first[w]]<<' '<<rp1[last[top[w]]]<<'\n';
        if(first[w] != -1 && last[top[w]] != -1 && rp1[last[top[w]]] <= rp1[first[w]]){
            //cout<<first[w]<<' '<<last[top[w]]<<' '<<id<<'\n';
            updstart(rp1[last[top[w]]],rp1[first[w]],id);
        }
        w = pr[top[w]];
    }
    if(dpth[u] > dpth[w])swap(u,w);
    if(first[w] != -1 && last[u] != -1 && rp1[last[u]] <= rp1[first[w]]){
        //cout<<last[u]<<' '<<first[w]<<' '<<id<<'\n';
        updstart(rp1[last[u]],rp1[first[w]],id);
    }
}
void addends(int u,int w,int id){
    w = prog(w,u);
    while(top[u] != top[w]){
        if(dpth[top[u]] > dpth[top[w]])swap(u,w);
        if(firen[w] != -1 && laen[top[w]] != -1 && rp2[laen[top[w]]] <= rp2[firen[w]]){
            //cout<<firen[w]<<' '<<laen[top[w]]<<' '<<id<<"end\n";
            updends(rp2[laen[top[w]]],rp2[firen[w]],id);
        }
        w = pr[top[w]];
    }
    if(dpth[u] > dpth[w])swap(u,w);
    if(firen[w] != -1 && laen[u] != -1 && rp2[laen[u]] <= rp2[firen[w]]){
        //cout<<laen[u]<<' '<<firen[w]<<' '<<id<<"end\n";
        updends(rp2[laen[u]],rp2[firen[w]],id);
    }
}
bool topsort(){
    int nr = 0;
    for(int i = 0;i < cnt;i++){
        deg[i] = 0;
    }
    for(int i = 0;i < cnt;i++){
        for(auto j:e2[i]){
            deg[j]++;
        }
    }
    for(int i = 0;i < cnt;i++){
        if(deg[i] == 0)q.push(i);
    }
    while(!q.empty()){
        int x = q.front();
        nr++;
        q.pop();
        for(auto i:e2[x]){
            deg[i]--;
            if(deg[i] == 0){
                q.push(i);
            }
        }
    }
    return nr == cnt;
}
void solve(){
    cnt3 = cnt4 = 0;
    cin>>n;
    for(int i = 0;i < n - 1;i++){
        int u,w;
        cin>>u>>w;
        u--;w--;
        e[w].push_back(u);
        e[u].push_back(w);
    }
    for(int i = 0;i < n;i++){
        starts[i] = -1;
        endz[i] = -1;
    }
    cin>>m;
    for(int i = 0;i < m;i++){
        int u,w;
        cin>>u>>w;
        u--;w--;
        starts[u] = i;
        endz[w] = i;
        su[i] = u;
        sw[i] = w;
    }
    cnt2 = 0;
    top[0] = 0;
    dfs(0, -1);
    dfs2(0, -1);
    cnt = m;
    root1 = cnt++;
    build1(0,m - 1,cnt - 1);
    root2 = cnt++;
    build2(0,m - 1,cnt - 1);
    /*for(int i = 0;i < n;i++){
        for(auto j:e2[i]){
            cout<<"edge:"<<i<<' '<<j<<'\n';
        }
    }*/
    for(int i = 0;i < n;i++){
        rmq[i][0] = pr[i];
        //cout<<first[i]<<' '<<last[i]<<' '<<i<<' '<<top[i]<<'\n';
    }
    for(int j = 1;j < logN;j++){
        for(int i = 0;i < n;i++){
            rmq[i][j] = rmq[rmq[i][j - 1]][j - 1];
        }
    }
    for(int i = 0;i < m;i++){
        int u = su[i];
        int w = sw[i];
        addstarts(u,w,i);
        addends(u,w,i);
    }
    bool ok = topsort();
    if(ok){
        cout<<"Yes\n";
    }else{
        cout<<"No\n";
    }
    for(int i = 0;i < n;i++){
        e[i].clear();
    }
    for(int i = 0;i < cnt;i++){
        e2[i].clear();
    }
}
int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
/**
1
12
1 2
1 3
3 4
4 5
5 6
7 8
7 9
9 10
10 11
11 12
1 7
6
1 8
2 11
3 12
4 9
5 10
6 7
**/

Compilation message (stderr)

jail.cpp: In function 'void dfs(int, int)':
jail.cpp:67:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   67 |     for(int i = 0;i < e[node].size();i++){
      |                   ~~^~~~~~~~~~~~~~~~
jail.cpp:76:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   76 |     for(int i = 0;i < e[node].size();i++){
      |                   ~~^~~~~~~~~~~~~~~~
#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...