Submission #1307450

#TimeUsernameProblemLanguageResultExecution timeMemory
1307450brandonallenJail (JOI22_jail)C++20
0 / 100
10 ms584 KiB
#ifdef LOCAL
#include "_pch.hpp"
#define USE_INPUT_FILE(file) freopen(file, "r", stdin);
#define USE_OUTPUT_FILE(file) freopen(file, "w", stdout);
#else
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define USE_INPUT_FILE(file)
#define USE_OUTPUT_FILE(file)
#endif

using namespace std;
using namespace __gnu_pbds;
using ll = long long;
using ull = unsigned long long;
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; // find_by_order(), order_of_key()
typedef tree<pair<ll,ll>, null_type, less<pair<ll,ll>>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
#define vll vector<ll>
#define vi vector<int>
#define counter(_) unordered_map<_,size_t>
#define fio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define fr(i,l,r) for (int i=l; i<r; ++i)
#define print(_) cout << _ << "\n";
#define printv(_) for (const auto& x : _) cout << x << ' '; cout << '\n';
#define printm(_) cout<<"{";for (const auto& kvp:_) cout<<kvp.first<<":"<<kvp.second<<","; cout<<"}\n";
#define si(_) string _; cin >> _;
#define ii(_) int _; cin >> _;
#define lli(_) ll _; cin >> _;
array<pair<int,int>,4> didj = {{{-1,0},{0,1},{1,0},{0,-1}}};
array<string,2> ny = {"No","Yes"};
ll inf = 151515151515151;
ll mod = 1000000007;
mt19937 rng(1);

vi adj[120001]; //neighbors of ith vertex in tree
int par[120001]; //parent of i in tree
int par1[120001]; //nearest tagged ancestor of i
pair<int,int> spt[18][240001]; //sparse table of euler tour: {depth, vertex}
int first[120001]; //first/last occurrence of i in euler tour
tuple<int,int,int> stl[120001]; //s/t vertices for ith prisoner
vector<tuple<int,int>> tag[120001]; //tag of ith vertex in tree: {0/1:s/t, jth prisoner, depth of lca of jth (s,t)}
vi top[120001]; //topological graph of prisoners
vi rev[120001]; //reverse topological graph of prisoners
int depth[120001]; //depth of ith vertex
int rt[120001]; //dsu parent
int id[120001]; //height control
int mn[120001]; //min depth vertex in component
int seen[120001]; //0: unseen, 1: seen and in stack, 2: completed

int find(int u) {
    int v = rt[u];
    while (v!=rt[v]) v = rt[v];
    rt[u] = v;
    return v;
}

int join(int u, int v) {
    u = find(u);
    v = find(v);
    if (u==v) return u;
    if (id[u]<id[v]) swap(u,v);
    rt[u] = v;
    mn[v] = min(mn[v],mn[u],[](int u, int v) { return depth[u]<depth[v]; });
    return v;
}

//{depth,vertex} lca of u and v
int lca(int u, int v) {
    // if (depth[u]<depth[v]) swap(u,v);
    int l1 = first[u];
    int l2 = first[v];
    int l = min(l1,l2);
    int r = max(l1,l2)+1;
    int sz = r-l, j;
    if (sz<=0) j = 0;
    else j = 31-__builtin_clz(sz);
    pair<int,int> res = spt[j][l];
    res = min(res, spt[j][r-(1<<j)]);
    return res.second;
}

void solve(int testcase) {
    ii(n);
    fill_n(adj,n,vi());
    fill_n(tag,n,vector<tuple<int,int>>());
    fr(i,0,n) id[i] = rng();
    fr(i,0,n-1) {
        ii(u); ii(v);
        u--; v--;
        adj[u].push_back(v);
    }

    //assign depth, parents, first/last occurrence, build tour
    stack<tuple<int,int>> st;
    st.emplace(0,1);
    par[0] = 0;
    depth[0] = 0;
    int tour_idx = 0;
    auto& tour = spt[0];
    while (!st.empty()) {
        auto [u,d] = st.top();
        st.pop();
        int p = par[u];
        if (d==0) {
            tour[tour_idx++] = {depth[p], p};
            continue;
        }
        first[u] = tour_idx;
        tour[tour_idx++] = {depth[u], u};
        st.emplace(u,0);
        for (auto v : adj[u]) {
            if (v==p) continue;
            par[v] = u;
            depth[v] = depth[u]+1;
            st.emplace(v,1);
        }
    }

    //build sparse table
    int k = tour_idx-1;
    int lim = 31-__builtin_clz(k);
    fr(j,1,lim+1) {
        fr(i,0,k+1-(1<<j)) {
            spt[j][i] = min(spt[j-1][i],spt[j-1][i+(1<<(j-1))]);
        }
    }
    ii(m);
    fr(i,0,m) {
        ii(s); ii(t);
        s--; t--;
        int l = lca(s,t);
        stl[i] = {s,t,l};
        tag[s].emplace_back(0,i);
        tag[t].emplace_back(1,i);
    }
    // if (testcase!=3) return;

    //create par1
    st.emplace(0,-1);
    while (!st.empty()) {
        auto [u,p] = st.top();
        st.pop();
        if (!tag[u].empty()) p = u;
        par1[u] = p;
        for (int v : adj[u]) {
            if (v==par[u]) continue;
            st.emplace(v,p);
        }
    }
    
    //assimilate ith prisoner into top/rev from s/t in path up to target depth from u
    auto path = [&](int i, int u, int d1, int type) {
        u = mn[find(u)];
        int d = depth[u];
        while (d>=d1) {
            int v = par1[u];
            if (v==-1 || depth[v]<d1) return;
            for (auto [type1,j] : tag[v]) {
                if (type!=type1 || i==j) continue;
                if (type==0) {
                    top[i].push_back(j);
                } else {
                    rev[j].push_back(i);
                }
            }
            if (u==0) break;
            u = par[mn[join(u,v)]];
            d = depth[u];
        }
    };
    //handle s in paths
    fill_n(top,m,vi());
    iota(rt,rt+n,0);
    iota(mn,mn+n,0);
    fr(i,0,m) {
        auto [s,t,l] = stl[i];
        path(i,s,depth[l],0);
        path(i,t,depth[l],0);
    }
    //handle t in paths
    fill_n(rev,m,vi());
    iota(rt,rt+n,0);
    iota(mn,mn+n,0);
    fr(i,0,m) {
        auto [s,t,l] = stl[i];
        path(i,s,depth[l],1);
        path(i,t,depth[l],1);
        top[i].insert(top[i].end(),rev[i].begin(),rev[i].end());
    }
    // fr(i,0,m) {
    //     print(i);
    //     printv(top[i]);
    //     print("___________");
    // }
    //check for cycle
    fill_n(seen,m,0);
    int res = 1;
    fr(i,0,m) {
        if (seen[i]==2) continue;
        st.emplace(i,1);
        while (!st.empty() && res==1) {
            auto [u,d] = st.top();
            st.pop();
            if (d==0) {
                seen[u] = 2;
                continue;
            }
            st.emplace(u,0);
            if (seen[u]==1) continue;
            seen[u] = 1;
            for (auto v : top[u]) {
                if (seen[v]==2) continue;
                if (seen[v]==1) {
                    res = 0;
                    break;
                }
                st.emplace(v,1);
            }
        }
    }
    print(ny[res]);
}

int main() {
    USE_INPUT_FILE("_input.txt");
    // USE_OUTPUT_FILE("_output.txt");
    fio;
    ii(testcases);
    fr(testcase,1,testcases+1) solve(testcase);
}
#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...