Submission #1215279

#TimeUsernameProblemLanguageResultExecution timeMemory
1215279mychecksedadJail (JOI22_jail)C++20
0 / 100
14 ms11848 KiB
/* Author : Mychecksdead */ #include<bits/stdc++.h> using namespace std; #define ll long long int #define MOD (1000000000+7) #define MOD1 (998244353) #define pb push_back #define all(x) x.begin(), x.end() #define en cout << '\n' #define ff first #define ss second #define pii pair<int,int> #define vi vector<int> const int N = 120100*4, M = 1e5+10, K = 20, MX = 30; int n, m, s[N], heavy[N], tin[N], tout[N], timer, par[N], up[N][K], dep[N]; vi g[N]; array<int, 2> a[N]; vector<set<int>> A, A2, B, B2; bool dead; vi vis; bool is_ancestor(int u, int v){ return tin[u] <= tin[v] && tout[v] <= tout[u]; } int _lca(int u, int v){ if(is_ancestor(u, v)) return u; if(is_ancestor(v, u)) return v; for(int j = K-1; j >= 0; --j){ if(!is_ancestor(up[u][j], v)) u = up[u][j]; } return up[u][0]; } void pre(int v, int p){ s[v] = 1; int big = -1; for(int &u: g[v]){ if(u != p){ pre(u, v); s[v] += s[u]; if(g[v][0] == p || s[g[v][0]] < s[u]) swap(u, g[v][0]); } } } void dfs(int v, int p){ tin[v] = timer++; up[v][0] = p; par[v] = p; dep[v] = dep[p] + 1; for(int u: g[v]){ if(u==p) continue; if(u == g[v][0]) heavy[u] = heavy[v]; else heavy[u] = u; dfs(u, v); } tout[v] = timer - 1; } // tp 1 void upd(int l, int r, int ql, int qr, int k, int val, vector<set<int>> &T){ if(ql > r || l > qr) return; if(ql <= l && r <= qr){ if(val > 0) T[k].insert(val); else T[k].erase(-val); return; } int mid = l+r>>1; upd(l, mid, ql, qr, k<<1, val, T); upd(mid+1, r, ql, qr, k<<1|1, val, T); } // tp 2 void upd2(int l, int r, int p, int k, int val, vector<set<int>> &T){ if(val > 0) T[k].insert(val); else T[k].erase(-val); if(l == r){ return; } int mid = l+r>>1; if(p <= mid) upd2(l, mid, p, k<<1, val, T); else upd2(mid+1, r, p, k<<1|1, val, T); } void put(int u, int v, int val, vector<set<int>> &T){ // do some hld // put val into path u...v int lca = _lca(u, v); while(u != lca){ if(dep[heavy[u]] > dep[lca]){ upd(1, n, tin[heavy[u]], tin[u], 1, val, T); u = par[heavy[u]]; }else{ upd(1, n, tin[lca], tin[u], 1, val, T); u = lca; } } u = v; while(u != lca){ if(dep[heavy[u]] > dep[lca]){ upd(1, n, tin[heavy[u]], tin[u], 1, val, T); u = par[heavy[u]]; }else{ upd(1, n, tin[lca] + 1, tin[u], 1, val, T); // avoid putting multiple at some point. u = lca; } } } int query(int l, int r, int ql, int qr, int k, vector<set<int>> &T, int other){ // check whether anyone on if(ql > r || l > qr) return 0; if(ql <= l && r <= qr) return T[k].empty() ? 0 : ((*T[k].begin()) == other ? (T[k].size() == 1 ? 0 : (*next(T[k].begin()))) : (*T[k].begin())); int mid = l+r>>1; return max(query(l, mid, ql, qr, k<<1, T, other), query(mid+1, r, ql, qr, k<<1|1, T, other)); } int query2(int l, int r, int p, int k, vector<set<int>> &T, int other){ // check whether anyone on if(T[k].size()) return T[k].empty() ? 0 : ((*T[k].begin()) == other ? (T[k].size() == 1 ? 0 : (*next(T[k].begin()))) : (*T[k].begin())); if(l == r) return T[k].empty() ? 0 : ((*T[k].begin()) == other ? (T[k].size() == 1 ? 0 : (*next(T[k].begin()))) : (*T[k].begin())); int mid = l+r>>1; if(p <= mid) return query2(l, mid, p, k<<1, T, other); return query2(mid+1, r, p, k<<1|1, T, other); } int query_path(int u, int v, vector<set<int>> &T, int other){ int lca = _lca(u, v); // cerr << u << ' ' << v << ' ' << lca << '\n'; while(u != lca){ if(dep[heavy[u]] > dep[lca]){ int x = query(1, n, tin[heavy[u]], tin[u], 1, T, other); if(x) return x; u = par[heavy[u]]; }else{ int x = query(1, n, tin[lca], tin[u], 1, T, other); if(x) return x; u = lca; } } u = v; while(u != lca){ if(dep[heavy[u]] > dep[lca]){ int x = query(1, n, tin[heavy[u]], tin[u], 1, T, other); if(x) return x; u = par[heavy[u]]; }else{ int x = query(1, n, tin[lca] + 1, tin[u], 1, T, other); if(x) return x; u = lca; } } return 0; } void DFS(int v){ // put v into the stack // cerr << v << '\n'; vis[v] = 1; put(a[v][0], a[v][1], -v, A); put(a[v][0], a[v][1], v, A2); upd2(1, n, tin[a[v][0]], 1, -v, B); upd2(1, n, tin[a[v][0]], 1, v, B2); // type 1 edges // check loop int b = query_path(a[v][0], a[v][1], B2, v); // this part will be fixed if(b > 0){ // cerr << " here\n"; dead = 1; // there is someone with vis[v] = 1. return; } int u = query_path(a[v][0], a[v][1], B, v); while(u){ DFS(u); u = query_path(a[v][0], a[v][1], B, v); } // type 2 edges b = query2(1, n, tin[a[v][1]], 1, A2, v); if(b > 0){ dead = 1; // cycle return; } u = query2(1, n, tin[a[v][1]], 1, A, v); while(u){ DFS(u); u = query2(1, n, tin[a[v][1]], 1, A, v); } // pop v vis[v] = 2; put(a[v][0], a[v][1], -v, A2); upd2(1, n, tin[a[v][0]], 1, -v, B2); } void solve(){ cin >> n; for(int i = 1; i <= n; ++i){ g[i].clear(); } for(int i = 1; i < n; ++i){ int u, v; cin >> u >> v; g[u].pb(v); g[v].pb(u); } cin >> m; vis.clear(); vis.resize(m + 1, 0); A.clear(); A.resize(4*n); A2.clear(); A2.resize(4*n); B2.clear(); B2.resize(4*n); B.clear(); B.resize(4*n); for(int i = 1; i <= m; ++i){ cin >> a[i][0] >> a[i][1]; } pre(1, 1); dep[1] = 0; timer = 1; heavy[1] = 1; dfs(1, 1); for(int j = 1; j < K; ++j){ for(int i = 1; i <= n; ++i){ up[i][j] = up[up[i][j - 1]][j - 1]; } } // for(int i = 1; i <= n; ++i){ // cerr << heavy[i] << '\n'; // } // return; for(int i = 1; i <= m; ++i){ put(a[i][0], a[i][1], i, A); // range put (B_j -> i edge) } for(int i = 1; i <= m; ++i){ upd2(1, n, tin[a[i][0]], 1, i, B); // point put (i -> A_j edge) } dead = false; for(int i = 1; i <= m; ++i){ if(vis[i] == 0 && !dead){ DFS(i); } } cout << (dead ? "No" : "Yes"); } int main(){ cin.tie(0); ios::sync_with_stdio(0); int tt = 1, aa; // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); cin >> tt; while(tt--){ solve(); en; } cerr<<"time taken : "<<(float)clock()/CLOCKS_PER_SEC<<" seconds\n"; return 0; }
#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...