Submission #999410

#TimeUsernameProblemLanguageResultExecution timeMemory
999410onbertJail (JOI22_jail)C++17
0 / 100
18 ms98392 KiB
#include <bits/stdc++.h> using namespace std; #define int long long const int maxn = 120005, maxN = 480005, lgn = 17, INF = 1e18; int n, m; vector<int> ADJ[maxn], adj[maxn]; pair<int,int> a[maxn]; int sz[maxn], d[maxn], newid[maxn], lim[maxn], cnter = 0; void dfs1(int u) { sz[u] = 1; int fa = -1; for (int &v:ADJ[u]) { if (sz[v]) { fa = v; continue; } dfs1(v); sz[u] += sz[v]; } if (fa!=-1) ADJ[u].erase(find(ADJ[u].begin(), ADJ[u].end(), fa)); for (int j=1;j<ADJ[u].size();j++) if (sz[ADJ[u][j]] > sz[ADJ[u][0]]) swap(ADJ[u][0], adj[u][j]); } void dfs2(int u) { cnter++; newid[u] = cnter; for (int v:ADJ[u]) dfs2(v); lim[u] = cnter; } pair<int, vector<pair<int,int>>> binlift[maxn][lgn]; void dfs3(int u) { for (int i=1;i<lgn;i++) { if (binlift[u][i-1].first==-1 || binlift[binlift[u][i-1].first][i-1].first==-1) break; binlift[u][i].first = binlift[binlift[u][i-1].first][i-1].first; binlift[u][i].second = binlift[u][i-1].second; for (auto [l, r]:binlift[binlift[u][i-1].first][i-1].second) { if (r+1==binlift[u][i].second.back().first) binlift[u][i].second.back().first = l; else binlift[u][i].second.push_back({l, r}); } } for (int v:adj[u]) { d[v] = d[u] + 1; binlift[v][0].first = u; dfs3(v); } } vector<pair<int,int>> path(int u, int v) { vector<pair<int,int>> U, V; if (d[u] > d[v]) swap(u, v); for (int i=lgn-1;i>=0;i--) if (d[v] - (1<<i) >= d[u]) { for (auto [l, r]:binlift[v][i].second) { if (V.size()>0 && r+1==V.back().first) V.back().first = l; else V.push_back({l, r}); // cout << l << " " << r << endl; } v = binlift[v][i].first; } if (u==v) return V; for (int i=lgn-1;i>=0;i--) if (binlift[u][i].first != binlift[v][i].first) { for (auto [l, r]:binlift[u][i].second) { if (U.size()>0 && r+1==U.back().first) U.back().first = l; else U.push_back({l, r}); } u = binlift[u][i].first; for (auto [l, r]:binlift[v][i].second) { if (V.size()>0 && r+1==V.back().first) V.back().first = l; else V.push_back({l, r}); } v = binlift[v][i].first; } int fa = binlift[v][0].first; if (U.size()>0 && u+1==U.back().first) U.back().first = u; else U.push_back({u, u}); if (V.size()>0 && v+1==V.back().first) V.back().first = v; else V.push_back({v, v}); if (V.size()>0 && fa+1==V.back().first) V.back().first = fa; else V.push_back({fa, fa}); // cout << "U" << endl; // for (auto [l, r]:U) cout << l << " " << r << endl; // cout << "V" << endl; // for (auto [l, r]:V) cout << l << " " << r << endl; // cout << endl; for (auto [l, r]:U) V.push_back({l, r}); return V; } struct node { int val, lpt, rpt; }; vector<node> seg[maxN][2]; void build(int id, int l, int r, int j) { seg[id][j] = {{INF, 0, 0}}; if (l==r) return; int mid = (l+r)/2; build(id*2, l, mid, j); build(id*2+1, mid+1, r, j); } void update(int id, int l, int r, int target, int val, int j) { if (r<target || target<l) return; if (l==r) { seg[id][j].push_back({val, -1, -1}); return; } int mid = (l+r)/2; update(id*2, l, mid, target, val, j); update(id*2+1, mid+1, r, target, val, j); seg[id][j].push_back({min(seg[id*2][j].back().val, seg[id*2+1][j].back().val), (int)seg[id*2][j].size()-1, (int)seg[id*2+1][j].size()-1}); } int qry(int id, int pt, int l, int r, int findl, int findr, int j) { if (r<findl || findr<l) return INF; if (findl<=l && r<=findr) return seg[id][j][pt].val; int mid = (l+r)/2; int lhs = qry(id*2, seg[id][j][pt].lpt, l, mid, findl, findr, j); int rhs = qry(id*2+1, seg[id][j][pt].rpt, mid+1, r, findl, findr, j); return min(lhs, rhs); } int lb(int l, int r, int x, int j) { // cout << l << " " << r << " " << x << " " << j << endl; // cout << qry(1, n-x+1, 1, n, l, r, j) << endl; return qry(1, n-x+1, 1, n, l, r, j); } void solve() { cin >> n; cnter = 0; for (int i=1;i<=n;i++) sz[i] = 0, adj[i].clear(), ADJ[i].clear(); for (int i=1;i<=n-1;i++) { int u, v; cin >> u >> v; ADJ[u].push_back(v); ADJ[v].push_back(u); } dfs1(1); dfs2(1); for (int u=1;u<=n;u++) for (int v:ADJ[u]) { adj[newid[u]].push_back(newid[v]); } for (int i=1;i<=n;i++) for (int j=0;j<lgn;j++) binlift[i][j] = {-1, {{i, i}}}; dfs3(1); // for (int i=1;i<=n;i++) { // cout << "node " << i << endl; // for (int j=0;j<lgn;j++) { // if (binlift[i][j].first==-1) break; // cout << binlift[i][j].first << " "; // } // cout << endl; // } cin >> m; int S[n+1], T[n+1]; for (int i=0;i<=n;i++) S[i] = T[i] = 0; a[0] = {1, INF}; for (int i=1;i<=m;i++) { int s, t; cin >> s >> t; s = newid[s], t = newid[t]; a[i] = {s, t}; S[s] = i, T[t] = i; } build(1, 1, n, 0); build(1, 1, n, 1); for (int i=n;i>=1;i--) { if (T[i]==0) seg[1][0].push_back(seg[1][0].back()); else update(1, 1, n, a[T[i]].first, i, 0); if (S[i]==0) seg[1][1].push_back(seg[1][1].back()); else update(1, 1, n, a[S[i]].second, i, 1); // if (T[i]!=0) cout << 0 << " " << a[T[i]].first << " " << i << endl; // if (S[i]!=0) cout << 1 << " " << a[S[i]].second << " " << i << endl; } for (int i=1;i<=m;i++) { auto [s, t] = a[i]; vector<pair<int,int>> cur = path(s, t); bool no = false; vector<pair<int,int>> Schild = {{s+1, lim[s]}}, Tchild = {{t+1, lim[t]}}; if (s <= t && t <= lim[s]) { int l; if (adj[s].back() <= t) l = adj[s].back(); else l = adj[s][upper_bound(adj[s].begin(), adj[s].end(), t)-adj[s].begin()-1]; int r = lim[l]; Schild = {{1, s-1}, {s+1, l-1}, {r+1, n}}; } else if (t <= s && s <= lim[t]) { int l; if (adj[t].back() <= s) l = adj[t].back(); else l = adj[t][upper_bound(adj[t].begin(), adj[t].end(), s)-adj[t].begin()-1]; int r = lim[l]; Tchild = {{1, t-1}, {t+1, l-1}, {r+1, n}}; } // cout << "S\n"; // for (auto [l, r]:Schild) cout << l << " " << r << endl; // cout << "T\n"; // for (auto [l, r]:Tchild) cout << l << " " << r << endl; for (auto [l, r]:cur) { // cout << "range " << l << " " << r << endl; for (auto [L, R]:Schild) no |= (lb(l, r, L, 0) <= R); for (auto [L, R]:Tchild) no |= (lb(l, r, L, 1) <= R); } for (auto [sl, sr]:Schild) for (auto[tl, tr]:Tchild) { no |= (lb(sl, sr, tl, 0) <= tr); no |= (lb(sl, sr, tl, 1) <= tr); } if (no) {cout << "No\n"; return;} } cout << "Yes\n"; } signed main() { ios::sync_with_stdio(0); cin.tie(0); int t; cin >> t; while (t--) solve(); }

Compilation message (stderr)

jail.cpp: In function 'void dfs1(long long int)':
jail.cpp:22:19: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   22 |     for (int j=1;j<ADJ[u].size();j++) if (sz[ADJ[u][j]] > sz[ADJ[u][0]]) swap(ADJ[u][0], adj[u][j]);
      |                  ~^~~~~~~~~~~~~~
#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...