제출 #1169093

#제출 시각아이디문제언어결과실행 시간메모리
1169093Troll321Inside information (BOI21_servers)C++20
5 / 100
3597 ms45900 KiB
#include <bits/stdc++.h> #define fi first #define se second using namespace std; typedef long long ll; typedef pair<ll, ll> pll; typedef pair<bool, bool> pbb; const ll MAXN = 120000 + 5; const ll MAXQ = 2*MAXN; const ll LOG = 17; const ll MAXLOG = LOG+5; ll n, k; pair<char, pll> query[MAXQ]; // {Type, {a, b}} ll parr[MAXN], depth[MAXN], sz[MAXN], heavy[MAXN]; vector<ll> adjl[MAXN]; struct segment { ll root = 0; vector<ll> nodes, seg; vector<pll> range; // {L, R} vector<pbb> extend; // {Lext, Rext} ll getIdx(ll node) { return depth[node] - depth[root]; } ll lb() {return 0;} ll rb() {return (ll)nodes.size()-1;} void addNode(ll node) { if(nodes.empty()) {root = node;} nodes.push_back(node); } void addEdge(ll idxa, ll idxb) { if(idxa > idxb) {swap(idxa,idxb);} // Extend A extend[idxa].se = ((range[idxb].se - range[idxb].fi) == 0); // Extend B extend[idxb].fi = ((range[idxa].se - range[idxa].fi) == 0); range[idxa].se = idxb; range[idxb].fi = idxa; } pll findL(ll idx) { if(extend[idx].fi && range[idx].fi != idx) { pll out = findL(range[idx].fi); range[idx].fi = out.fi; extend[idx].fi = out.se; return {range[idx].fi, extend[idx].fi}; } return {range[idx].fi, extend[idx].fi}; } // {Range, Ext} pll findR(ll idx) { if(extend[idx].se && range[idx].se != idx) { pll out = findR(range[idx].se); range[idx].se = out.fi; extend[idx].se = out.se; return {range[idx].se, extend[idx].se}; } return {range[idx].se, extend[idx].se}; } pll find(ll idx) { return {findL(idx).fi, findR(idx).fi}; } bool data(ll idxa, ll idxb) { // Apakah idxb nyampe idxa pll out = find(idxb); return ((out.fi <= idxa && idxa <= out.se) ? true : false); } ll count(ll idxa) { pll out = find(idxa); return (out.se - out.fi + 1); } void build(ll pos, ll l, ll r) { if(l == r) { seg[pos] = 1; return ; } ll mid = (l+r)/2; build(pos*2, l, mid); build(pos*2+1, mid+1, r); seg[pos] = seg[pos*2] + seg[pos*2+1]; } void init() { seg.resize(nodes.size()*4); for (int i = 0; i < nodes.size(); ++i) { range.push_back({i,i}); extend.push_back({true,true}); } build(1, lb(), rb()); } void update(ll pos, ll l, ll r, ll idx, ll x) { if(l > idx || r < idx) { return ; } if(idx <= l && r <= idx) { seg[pos] = x; return ; } ll mid = (l+r)/2; update(pos*2, l, mid, idx, x); update(pos*2+1, mid+1, r, idx, x); seg[pos] = seg[pos*2] + seg[pos*2+1]; } ll query(ll pos, ll l, ll r, ll idxa, ll idxb) { if(l > idxb || r < idxa) { return 0; } if(idxa <= l && r <= idxb) { return seg[pos]; } ll mid = (l+r)/2; return ( query(pos*2, l, mid, idxa, idxb) + query(pos*2+1, mid+1, r, idxa, idxb) ); } }; segment segs[MAXN]; void dfs(ll now, ll par) { parr[now] = par; depth[now] = depth[par]+1; sz[now] = 1; for(ll nxt : adjl[now]) { if(nxt == par) {continue ;} dfs(nxt, now); sz[now] += sz[nxt]; } } void addHeavy(ll node, ll hidx) { segs[hidx].addNode(node); } void hld(ll now, ll par) { ll mx = -1, nowHeavy = -1; for(ll nxt : adjl[now]) { if(nxt == par) {continue ;} if(sz[nxt] > mx) { mx = sz[nxt]; nowHeavy = nxt; } } if(heavy[now] == 0) { if (now == par) { heavy[now] = nowHeavy; addHeavy(now, heavy[now]); } else { heavy[now] = now; addHeavy(par, heavy[now]); addHeavy(now, heavy[now]); } } if(nowHeavy != -1) { heavy[nowHeavy] = heavy[now]; addHeavy(nowHeavy, heavy[now]); } for(ll nxt : adjl[now]) { if(nxt == par) {continue ;} hld(nxt, now); } } void initSegs() { for (int i = 1; i <= n; ++i) { if(segs[i].nodes.empty()) {continue ;} segs[i].init(); } } void addEdge(ll a, ll b) { if(depth[a] < depth[b]) {swap(a, b);} segment* s = &segs[heavy[a]]; (*s).addEdge((*s).getIdx(b), (*s).getIdx(a)); while(true) { pll range = (*s).find(0); ll ncnt = (*s).query(1, (*s).lb(), (*s).rb(), range.fi, range.se); ll now = (*s).root; s = &segs[heavy[now]]; (*s).update(1, (*s).lb(), (*s).rb(), (*s).getIdx(now), ncnt); if(heavy[(*s).root] == heavy[now]) { break ; } } } void ask(ll a, ll b) { // Apakah b mencapai a ll ans = -1; while(true) { if(heavy[a] == heavy[b]) { segment* s = &segs[heavy[a]]; ll ida = (*s).getIdx(a); ll idb = (*s).getIdx(b); ll hasil = (*s).data(ida, idb); ans = hasil; break ; } else { if(depth[heavy[a]] < depth[heavy[b]]) { // Naikin B segment* s = &segs[heavy[b]]; ll idb = (*s).getIdx(b); ll hasil = (*s).data(0, idb); ans = hasil; if(!hasil) {break ;} b = (*s).root; } else { // Naikin A segment* s = &segs[heavy[a]]; ll ida = (*s).getIdx(a); ll hasil = (*s).data(ida, 0); ans = hasil; if(!hasil) {break ;} a = (*s).root; } } } cout << (ans ? "yes" : "no") << "\n"; } void count(ll a) { ll ans = 0; while(true) { segment* s = &segs[heavy[a]]; pll range = (*s).find((*s).getIdx(a)); ll hasil = (*s).query(1, (*s).lb(), (*s).rb(), range.fi, range.se); ans += hasil; if(range.fi == 0) { if(heavy[(*s).root] == heavy[a]) {break ;} a = (*s).root; } } cout << ans << "\n"; } void solve() { cin >> n >> k; for (int i = 1; i <= n+k-1; ++i) { cin >> query[i].fi; switch(query[i].fi) { case 'S': cin >> query[i].se.fi >> query[i].se.se; adjl[query[i].se.fi].push_back(query[i].se.se); adjl[query[i].se.se].push_back(query[i].se.fi); break ; case 'Q': cin >> query[i].se.fi >> query[i].se.se; break ; case 'C': cin >> query[i].se.fi; break ; } } dfs(1, 1); hld(1, 1); initSegs(); for (int i = 1; i <= n+k-1; ++i) { switch(query[i].fi) { case 'S': addEdge(query[i].se.fi, query[i].se.se); break ; case 'Q': ask(query[i].se.fi, query[i].se.se); break ; case 'C': count(query[i].se.fi); break ; } } } int main() { // ios_base::sync_with_stdio(false); cin.tie(0); solve(); 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...
#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...