Submission #860372

#TimeUsernameProblemLanguageResultExecution timeMemory
860372KiaRezJail (JOI22_jail)C++17
100 / 100
1109 ms453064 KiB
/* IN THE NAME OF GOD */ #include <bits/stdc++.h> // #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") // #pragma GCC optimize("O3") // #pragma GCC optimize("unroll-loops") using namespace std; typedef long long ll; typedef pair<ll, ll> pll; typedef pair<int, int> pii; typedef pair<int, pii> ipii; typedef pair<pii, int> piii; typedef pair<ll, pll> lpll; typedef pair<pll, ll> plll; typedef pair<pii, pii> piipii; typedef pair<pll, pll> pllpll; typedef long double ld; #define F first #define S second #define Mp make_pair #define pb push_back #define pf push_front #define size(x) ((ll)x.size()) #define all(x) (x).begin(),(x).end() #define kill(x) cout << x << '\n', exit(0); #define set_dec(x) cout << fixed << setprecision(x); #define fuck(x) cout << "(" << #x << " , " << x << ")" << endl #define endl '\n' const int N = 2e5+23, lg = 18; ll Mod = 1e9+7; //ll Mod = 998244353; inline ll MOD(ll a, ll mod=Mod) { a%=mod; (a<0)&&(a+=mod); return a; } inline ll max(ll a, ll b) {return (a>b ? a : b);} inline ll min(ll a, ll b) {return (a<b ? a : b);} inline ll abso(ll a) {return (a<0?-a:a);} inline ll poww(ll a, ll b, ll mod=Mod) { ll ans = 1; a=MOD(a, mod); while (b) { if (b & 1) ans = MOD(ans*a, mod); b >>= 1; a = MOD(a*a, mod); } return ans; } struct Node { int deg; vector<int> adj; Node() { deg=0; } } node[N*38]; int q, n, m, cnt, h[N], par[lg][N], s[N], t[N], rs[N], rt[N]; int fakes[lg][N], faket[lg][N]; vector<int> tree[N]; void add(int v, int u) { if(v==0 || u==0 || v==u) return; node[v].adj.pb(u); node[u].deg++; } void init(int v, int p=0) { par[0][v]=p, h[v]=h[p]+1; for(int i=1; i<lg; i++) { par[i][v] = par[i-1][par[i-1][v]]; } for(int i=0; i<lg; i++) { fakes[i][v] = ++cnt; faket[i][v] = ++cnt; } int tmp = v; add(faket[0][v], rt[tmp]); tmp = par[0][v]; add(faket[0][v], rt[tmp]); tmp = v; add(rs[tmp], fakes[0][v]); tmp = par[0][v]; add(rs[tmp], fakes[0][v]); for(int i=1; i<lg; i++) { add(faket[i][v], faket[i-1][v]); add(faket[i][v], faket[i-1][par[i-1][v]]); add(fakes[i-1][v], fakes[i][v]); add(fakes[i-1][par[i-1][v]], fakes[i][v]); } for(int u : tree[v]) { if(u == p) continue; init(u, v); } } int getPar(int v, int dist) { for(int i=0; i<lg; i++) { if((dist>>i)%2) { v = par[i][v]; } } return v; } int LCA(int v, int u) { if(h[u] < h[v]) swap(v,u); u = getPar(u, h[u]-h[v]); if(v == u) return v; for(int i=lg-1; i>=0; i--) { if(par[i][v] != par[i][u]) { v=par[i][v], u=par[i][u]; } } return par[0][v]; } void addPaths(int cnd, int v, int dist) { if(dist<0 || cnd==0 || v==0) return; //cout<<"addPath : "<<cnd<<' '<<v<<' '<<dist<<endl; if(dist == 0) { //add(cnd, rt[v]); add(rs[v], cnd); return; } for(int i=0; i<lg; i++) { if((dist>>i)%2==1) { //cout<<"edge : "<<cnd<<" ===> ("<<i<<", "<<v<<")\n"; //add(cnd, faket[i][v]); //cout<<"edge : "<<cnd<<" <=== ("<<i<<", "<<v<<")\n"; add(fakes[i][v], cnd); v = par[i][v]; } } return; } void addPatht(int cnd, int v, int dist) { if(dist<0 || cnd==0 || v==0) return; //cout<<"addPath : "<<cnd<<' '<<v<<' '<<dist<<endl; if(dist == 0) { add(cnd, rt[v]); return; } for(int i=0; i<lg; i++) { if((dist>>i)%2==1) { //cout<<"edge : "<<cnd<<" ===> ("<<i<<", "<<v<<")\n"; add(cnd, faket[i][v]); //cout<<"edge : "<<cnd<<" <=== ("<<i<<", "<<v<<")\n"; //add(fakes[i][v], cnd); v = par[i][v]; } } return; } void solve() { cin>>n; for(int v,u,i=1; i<n; i++) { cin>>v>>u; tree[v].pb(u); tree[u].pb(v); } cin>>m; for(int i=1; i<=m; i++) { cin>>s[i]>>t[i]; rs[s[i]] = i; rt[t[i]] = i; } cnt = m; init(1); for(int i=1; i<=m; i++) { int lca = LCA(s[i], t[i]); //int ff = (s[i]==lca || t[i]==lca); addPaths(i, par[0][s[i]], h[par[0][s[i]]] - h[lca]); addPatht(i, s[i], h[s[i]] - h[lca] - (t[i]==lca)); addPaths(i, t[i], h[t[i]] - h[lca] - (s[i]==lca)); addPatht(i, par[0][t[i]], h[par[0][t[i]]] - h[lca]); } int cnt2=0; queue<int> q; for(int i=1; i<=cnt; i++) { if(node[i].deg == 0) q.push(i); } while(size(q)) { int v = q.front(); q.pop(); cnt2 ++; for(int u : node[v].adj) { node[u].deg--; if(node[u].deg==0) { q.push(u); } } } //fuck(cnt); fuck(cnt2); if(cnt2 == cnt) cout<<"Yes\n"; else cout<<"No\n"; } /* node[N*20]; int q, n, m, cnt, h[N], par[lg][N], s[N], t[N], rs[N], rt[N]; int fakes[lg][N], faket[lg][N]; vector<int> tree[N]; */ void reset() { for(int i=0; i<=n+2; i++) { h[i]=s[i]=t[i]=rs[i]=rt[i]=0; for(int j=0; j<lg; j++) { fakes[j][i]=faket[j][i]=0; } while(size(tree[i])) tree[i].pop_back(); } for(int i=0; i<=cnt; i++) { node[i].deg=0; while(size(node[i].adj)) node[i].adj.pop_back(); } } int main () { ios_base::sync_with_stdio(false), cin.tie(0); cin>>q; while(q--) { solve(); reset(); } 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...