Submission #815127

#TimeUsernameProblemLanguageResultExecution timeMemory
815127WonderfulWhaleJail (JOI22_jail)C++17
100 / 100
3523 ms308640 KiB
//#pragma GCC optimize("O3,unroll-loops") #include <bits/stdc++.h> using namespace std; #define pii pair<int, int> #define st first #define nd second #define pb push_back #define all(x) (x).begin(), (x).end() #define sz(x) (int)(x).size() int Gg = 0; int col[120009]; bool dfs2(int x); struct SegTree { int T=1; vector<unordered_set<int>> t; void build(int n) { T=1; while(T<=n) T*=2; t.resize(2*T); for(int i=0;i<2*T;i++) t[i].clear(); } bool help(int x, int s) { while(sz(t[x])) { auto it = t[x].begin(); if(*it==s) { //cerr << "tutaj\n"; if(sz(t[x])==1) break; it++; } int y = *it; //cout << s << " -> " << y << "\n"; if(col[y]==1) return false; if(col[y]==0&&!dfs2(y)) return false; } return true; } bool query(int l, int r, int s) { //cout << "query: " << l << " " << r << "\n"; l+=T, r+=T; if(!help(l, s)) return false; if(l!=r&&!help(r, s)) return false; while(l/2!=r/2) { if(l%2==0&&!help(l+1, s)) return false; if(r%2==1&&!help(r-1, s)) return false; l/=2; r/=2; } return true; } void add(int x, int val) { x+=T; while(x) { t[x].insert(val); x/=2; } } void remove(int x, int val) { x+=T; while(x) { t[x].erase(val); x/=2; } } }; struct SegTree2 { int T = 1; vector<unordered_set<int>> t; void build(int n) { T=1; while(T<=n) T*=2; t.resize(2*T); for(int i=0;i<2*T;i++) t[i].clear(); } void add(int l, int r, int val) { //cout << "add: "<< l << " " << r << " " << val << "\n"; l+=T, r+=T; t[l].insert(val); if(l!=r) t[r].insert(val); while(l/2!=r/2) { if(l%2==0) t[l+1].insert(val); if(r%2==1) t[r-1].insert(val); l/=2; r/=2; } } void remove(int l, int r, int val) { //cout << "remove: "<< l << " " << r << " " << val << "\n"; l+=T, r+=T; t[l].erase(val); if(l!=r) t[r].erase(val); while(l/2!=r/2) { if(l%2==0) t[l+1].erase(val); if(r%2==1) t[r-1].erase(val); l/=2; r/=2; } } bool help(int x, int s) { while(sz(t[x])) { //cerr << "tutaj2\n"; auto it = t[x].begin(); if(*it==s) { if(sz(t[x])==1) break; it++; } int y = *it; //cout << s << " -> " << y << "\n"; //cout << s << " " << y << " " << col[y] << "\n"; if(col[y]==1) return false; if(col[y]==0&&!dfs2(y)) return false; } return true; } bool query(int x, int s) { //cout << "zaczynamy!!!\n"; x+=T; while(x) { if(!help(x, s)) return false; x/=2; } return true; } }; vector<int> G[120009]; vector<int> G2[120009]; int tin[120009], tout[120009], T; int jp2[120009][20]; int deg[120009]; pii tab[120009]; int dep[120009]; int p[120009]; int heavy[120009]; int pos[120009], P; int head[120009]; int dfs(int x, int y) { p[x] = y; dep[x] = dep[y]+1; int sz = 1, max_sz=0; tin[x] = ++T; jp2[x][0] = y; for(int i=1;i<20;i++) jp2[x][i] = jp2[jp2[x][i-1]][i-1]; for(int z:G[x]) if(z!=y) { int c_sz = dfs(z, x); sz += c_sz; if(c_sz>max_sz) { max_sz = c_sz; heavy[x] = z; } } tout[x] = ++T; return sz; } void decompose(int x, int h) { head[x] = h; pos[x] = ++P; if(heavy[x]) { decompose(heavy[x], h); } for(int y:G[x]) { if(y!=p[x]&&y!=heavy[x]) decompose(y, y); } } bool is_ancestor(int x, int y) { return tin[x]<=tin[y]&&tout[x]>=tout[y]; } int lca(int x, int y) { if(is_ancestor(x, y)) return x; if(is_ancestor(y, x)) return y; for(int i=19;i>=0;i--) { if(!is_ancestor(jp2[x][i], y)) { x = jp2[x][i]; } } return jp2[x][0]; } bool is_on_path(int x, int a, int b) { return is_ancestor(a, x)&&is_ancestor(x, b); } bool f(int x, int a, int b) { int y = lca(a, b); //cerr << "lca: " << a << " " << b << " " << y << "\n"; //cerr << "checking: " << x << " " << a << " " << b << " " << (is_on_path(x, y, a)||is_on_path(x, y, b)) << "\n"; return is_on_path(x, y, a)||is_on_path(x, y, b); } SegTree seg1; SegTree2 seg2; bool hld_query(int a, int b, int s) { //cout << "hld_query: " << a << " " << b << "\n"; vector<int> ret; for (; head[a] != head[b]; b=p[head[b]]) { if (dep[head[a]] > dep[head[b]]) swap(a, b); if(!seg1.query(pos[head[b]], pos[b], s)) return false; } if (dep[a] > dep[b]) swap(a, b); if(!seg1.query(pos[a], pos[b], s)) return false; return true; } void hld_add(int a, int b, int val) { //cout << "hld_query: " << a << " " << b << "\n"; vector<int> ret; for (; head[a] != head[b]; b=p[head[b]]) { if (dep[head[a]] > dep[head[b]]) swap(a, b); seg2.add(pos[head[b]], pos[b], val); } if (dep[a] > dep[b]) swap(a, b); seg2.add(pos[a], pos[b], val); } void hld_remove(int a, int b, int val) { //cout << "hld_query: " << a << " " << b << "\n"; vector<int> ret; for (; head[a] != head[b]; b=p[head[b]]) { if (dep[head[a]] > dep[head[b]]) swap(a, b); seg2.remove(pos[head[b]], pos[b], val); } if (dep[a] > dep[b]) swap(a, b); seg2.remove(pos[a], pos[b], val); } int N; bool dfs2(int x) { assert(col[x]==0); col[x] = 1; //cout << "dfs: " << x << "\n"; if(!hld_query(tab[x].st, tab[x].nd, x)) return false; if(!seg2.query(pos[tab[x].nd], x)) return false; col[x] = 2; seg1.remove(pos[tab[x].st], x); //cout << "removing: " << x << "\n"; hld_remove(tab[x].st, tab[x].nd, x); return true; } int32_t main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int q=1; cin >> q; while(q--) { int n, m; cin >> n; N = n; Gg=0; for(int i=1;i<=n;i++) { G[i].clear(); head[i] = 0; heavy[i] = 0; dep[i] = 0; p[i] = 0; } for(int i=0;i<n-1;i++) { int a, b; cin >> a >> b; G[a].pb(b); G[b].pb(a); } tin[0] = T = 0; dfs(1, 0); P = 0; decompose(1, 1); tout[0] = T; cin >> m; for(int i=0;i<m;i++) { G2[i].clear(); deg[i] = 0; col[i] = 0; } seg1.build(n+9); seg2.build(n+9); for(int i=0;i<m;i++) { cin >> tab[i].st >> tab[i].nd; seg1.add(pos[tab[i].st], i); hld_add(tab[i].st, tab[i].nd, i); } bool ans = true; for(int i=0;i<m;i++) { if(!ans) continue; if(!col[i]) { ans&=dfs2(i); } } if(ans) { cout << "Yes\n"; } else { cout << "No\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...