Submission #1001727

#TimeUsernameProblemLanguageResultExecution timeMemory
1001727amine_arouaInside information (BOI21_servers)C++17
2.50 / 100
292 ms100648 KiB
#include <bits/stdc++.h> //#pragma GCC optimize("O3") //#pragma GCC optimize("unroll-loops") using namespace std; #define int long long #define pb push_back #define nl '\n' #define fore(i, y) for(int i = 0; i < y; i++) #define forr(i, x, y) for(int i = x;i<=y;i++) #define forn(i, y, x) for(int i = y; i >= x; i--) const int N = 2e5 + 10; vector<pair<int ,int>> adj[N]; int subtree[N] ; int belongs[N]; bool forbidden[N]; int join[N] , up[N]; bool decre[N] , incre[N]; void dfs_subtree(int x ,int p) { subtree[x] = 1; for(auto [u,i] :adj[x]) { if(u == p || forbidden[u]) continue; dfs_subtree(u , x); subtree[x]+=subtree[u]; } } int dfs_down(int x , int p ,int n) { for(auto [u,i] : adj[x]) { if(u == p || forbidden[u]) continue; if(subtree[u] > n/2) return dfs_down(u , x , n); } return x; } vector<int> nodes; void dfs_belong(int x , int p , int child , int edge_p , int edge_join) { nodes.pb(x); belongs[x] = child; up[x] = edge_p; join[x] = edge_join; for(auto [u , i] : adj[x]) { if(u == p || forbidden[u]) continue; dfs_belong(u , x , child , i , edge_join); } } void dfs_incre(int x , int p , int edge_p) { incre[x] = 1; for(auto [u,i] : adj[x]) { if(u == p || forbidden[u]) continue; if(i <= edge_p) continue; dfs_incre(u , x , i); } } void dfs_decre(int x , int p , int edge_p) { decre[x] = 1; for(auto [u,i] : adj[x]) { if(u == p || forbidden[u]) continue; if(i >= edge_p) continue; dfs_decre(u , x , i); } } int ans[N]; vector<vector<int>> queries_in_subtree[N]; void rec(int root , vector<vector<int>> queries) { vector<int>().swap(nodes); vector<vector<int>>().swap(queries_in_subtree[root]); dfs_subtree(root , -1); int centroid = dfs_down(root ,-1 , subtree[root]); incre[centroid] = 1; decre[centroid] = 1; belongs[centroid] = centroid; for(auto [child,i] : adj[centroid]) { if(!forbidden[child]) { dfs_belong(child , centroid , child , i , i); dfs_incre(child , centroid , i); dfs_decre(child , centroid , i); } } for(auto query : queries) { int a = query[0] , b = query[1] , id = query[2]; if(belongs[a] != belongs[b]) { if(a == centroid) { ans[id] = (decre[b] && join[b] < id); } else if(b == centroid) { ans[id] = (incre[a] && up[a] < id); } else ans[id] = (incre[a] && decre[b] && join[a] > join[b] && up[a] < id); } else { queries_in_subtree[belongs[a]].pb(query); } } for(auto node : nodes) decre[node] = incre[node] = 0; forbidden[centroid] = 1; for(auto [u,i] : adj[centroid]) { if(!forbidden[u]) rec(u , queries_in_subtree[u]); } } signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n , q; cin>>n>>q; vector<vector<int>> queries; vector<char> type; fore(i , n + q - 1) { char c; cin>>c; type.pb(c); if(c == 'S') { int a , b; cin>>a>>b; adj[a].pb({b , i}); adj[b].pb({a , i}); } if(c == 'Q') { int a , d; cin>>a>>d; if(a == d) ans[i] = 1; else queries.pb({a , d , i}); } } rec(1 , queries); fore(i , n + q - 1) { if(type[i] == 'Q') { cout<<(ans[i] ? "yes" : "no")<<nl; } } }
#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...
#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...