제출 #1145291

#제출 시각아이디문제언어결과실행 시간메모리
1145291Zbyszek99Inside information (BOI21_servers)C++20
0 / 100
30 ms11708 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define ll long long #define ld long double #define ull unsigned long long #define ff first #define ss second #define pii pair<int,int> #define pll pair<long long, long long> #define vi vector<int> #define vl vector<long long> #define pb push_back #define rep(i, b) for(int i = 0; i < (b); ++i) #define rep2(i,a,b) for(int i = a; i <= (b); ++i) #define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c) #define count_bits(x) __builtin_popcountll((x)) #define all(x) (x).begin(),(x).end() #define siz(x) (int)(x).size() #define forall(it,x) for(auto& it:(x)) using namespace __gnu_pbds; using namespace std; typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set; //mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());} //ll los(ll a, ll b) {return a + (mt() % (b-a+1));} const int INF = 1e9+50; const ll INF_L = 1e18+40; const ll MOD = 1e9+7; struct node { int l = 0; int r = (1 << 17)-1; node* left; node* right; bool is_l = 0; bool is_r = 0; int sum = 0; void getl() { if(is_l) return; left = new node; left -> l = l; left -> r = (l+r)/2; is_l = 1; } void getr() { if(is_r) return; right = new node; right -> l = (l+r)/2+1; right -> r = r; is_r = 1; } int get_sum(int p1, int p2) { if(r < p1 || l > p2) return 0; if(l >= p1 && r <= p2) return sum; getl(); getr(); return left->get_sum(p1,p2) + right->get_sum(p1,p2); } void add(int ind, int x) { if(l == r) { sum += x; return; } getl();getr(); if(ind <= (l+r)/2) left->add(ind,x); else right->add(ind,x); sum = left->sum + right->sum; } }; struct query { int type,a,b; }; struct centr_str { int centr, path_type, edge, out_edge; }; vector<query> queries; vector<pii> graph[120'001]; vector<centr_str> centroids[120'001]; bitset<120'001> odw; int subtree[120'001]; node seg_tree[120'001]; void calc_subtree(int v, int pop) { subtree[v] = 1; forall(it,graph[v]) { if(it.ff != pop && !odw[it.ff]) { calc_subtree(it.ff,v); subtree[v] += subtree[it.ff]; } } } void calc_paths(int v, int pop, int path_type, int pop_edge, int centr, int start_edge) { centroids[v].pb({centr,path_type,start_edge,pop_edge}); if(v == centr) { forall(it,graph[v]) { if(it.ff != pop && !odw[it.ff]) { calc_paths(it.ff,v,0,it.ss,centr,it.ss); } } } else { forall(it,graph[v]) { if(it.ff != pop && !odw[it.ff]) { if(path_type == 0) { if(it.ss < pop_edge) { calc_paths(it.ff,v,1,it.ss,centr,start_edge); } else { calc_paths(it.ff,v,2,it.ss,centr,start_edge); } } if(path_type == 1) { if(it.ss < pop_edge) { calc_paths(it.ff,v,1,it.ss,centr,start_edge); } else { calc_paths(it.ff,v,-1,it.ss,centr,start_edge); } } if(path_type == 2) { if(it.ss > pop_edge) { calc_paths(it.ff,v,2,it.ss,centr,start_edge); } else { calc_paths(it.ff,v,-1,it.ss,centr,start_edge); } } } } } } void centroid(int v, int n) { // cout << v << " start\n"; calc_subtree(v,v); int pop = -1; while(true) { pii maks = {-1,-1}; forall(it,graph[v]) { if(it.ff != pop && !odw[it.ff]) { // cout << it.ff << " " << odw[it.ff] << " " << subtree[it.ff] << " subntree\n"; maks = max(maks,{subtree[it.ff],it.ff}); } } if(maks.ff > n/2) { pop = v; v = maks.ss; } else break; } // cout << v << " centr\n"; calc_subtree(v,v); odw[v] = 1; calc_paths(v,v,0,-1,v,(1 << 17)-2); if(n == 1) return; forall(it,graph[v]) { if(!odw[it.ff]) { centroid(it.ff,subtree[it.ff]); } } } void upd_v(int v, int query_ind) { forall(it,centroids[v]) { if(it.out_edge != query_ind || it.centr == v) continue; // cout << "upd " << v << " " << it.centr << " " << it.edge << " edge\n"; if(it.path_type == 2 || it.path_type == 0) { seg_tree[it.centr].add(it.edge,1); } } // cout << "\n"; } int main() { ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); //random_start(); int n,k; cin >> n >> k; rep(i,n+k-1) { char t; cin >> t; if(t == 'S') { int a,b; cin >> a >> b; graph[a].pb({b,i}); graph[b].pb({a,i}); queries.pb({0,a,b}); } if(t == 'Q') { int a,b; cin >> a >> b; queries.pb({1,a,b}); } if(t == 'C') { int x; cin >> x; queries.pb({2,x,-1}); } } centroid(1,n); int query_ind = 0; rep2(i,1,n) { seg_tree[i].add((1 << 17)-2,1); } forall(it,queries) { if(it.type == 0) { upd_v(it.a,query_ind); upd_v(it.b,query_ind); } if(it.type == 1) { bool ans = 0; rep(i,min(siz(centroids[it.a]),siz(centroids[it.b]))) { // cout << centroids[it.a][i].centr << " " << centroids[it.a][i].path_type << " " << centroids[it.a][i].edge << " " << centroids[it.a][i].out_edge << " centr a\n"; // cout << centroids[it.b][i].centr << " " << centroids[it.b][i].path_type << " " << centroids[it.b][i].edge << " " << centroids[it.b][i].out_edge << " centr b\n\n"; if(centroids[it.a][i].out_edge > query_ind) continue; if(centroids[it.a][i].centr == centroids[it.b][i].centr) { if(centroids[it.b][i].centr == it.b && (centroids[it.a][i].path_type == 2 || centroids[it.a][i].path_type == 0)) { ans = 1; break; } if(centroids[it.a][i].centr == it.a && (centroids[it.b][i].path_type == 1 || centroids[it.b][i].path_type == 1)) { ans = 1; break; } if((centroids[it.a][i].path_type == 0 || centroids[it.a][i].path_type == 2) && (centroids[it.b][i].path_type == 1 || centroids[it.b][i].path_type == 0) && centroids[it.b][i].edge < centroids[it.a][i].edge) { ans = 1; break; } } } if(ans == 1) { cout << "yes\n"; } else { cout << "no\n"; } } if(it.type == 2) { int ans = 0; forall(it2,centroids[it.a]) { if(it2.path_type == 0 || it2.path_type == 1) { if(it2.centr != it.a) ans += seg_tree[it2.centr].get_sum(it2.edge+1,(1 << 17)-2); else ans += seg_tree[it2.centr].get_sum(0,(1 << 17)-2); } } cout << ans << "\n"; } query_ind++; } }
#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...