Submission #588757

#TimeUsernameProblemLanguageResultExecution timeMemory
588757maomao90Inside information (BOI21_servers)C++17
100 / 100
761 ms162796 KiB
// Hallelujah, praise the one who set me free // Hallelujah, death has lost its grip on me // You have broken every chain, There's salvation in your name // Jesus Christ, my living hope #include <bits/stdc++.h> using namespace std; #define REP(i, s, e) for (int i = (s); i < (e); i++) #define RREP(i, s, e) for (int i = (s); i >= (e); i--) template <class T> inline bool mnto(T& a, T b) {return a > b ? a = b, 1 : 0;} template <class T> inline bool mxto(T& a, T b) {return a < b ? a = b, 1: 0;} typedef long long ll; typedef long double ld; #define FI first #define SE second typedef pair<int, int> ii; typedef pair<ll, ll> pll; typedef tuple<int, int, int> iii; #define ALL(_a) _a.begin(), _a.end() #define SZ(_a) (int) _a.size() #define pb push_back typedef vector<int> vi; typedef vector<ll> vll; typedef vector<ii> vii; typedef vector<iii> viii; #ifndef DEBUG #define cerr if (0) cerr #endif const int INF = 1000000005; const ll LINF = 1000000000000000005ll; const int MAXN = 300005; const int MAXL = 20; struct Qry { char t; int a, b; }; struct Edge { int v, lo, hi; bool inc, dec; Edge operator+ (const Edge &o) const { if (v == -1) { return o; } if (o.v == -1) { return *this; } Edge res; res.v = o.v; res.lo = lo; res.hi = o.hi; res.inc = inc && o.inc && hi < o.lo; res.dec = dec && o.dec && hi > o.lo; return res; } Edge operator~ () const { return {v, hi, lo, dec, inc}; } friend ostream& operator<< (ostream &os, const Edge &o) { return os << "(" << o.v << ' ' << o.lo << ' ' << o.hi << ' ' << o.inc << ' ' << o.dec << ")"; } }; int n, k; vector<Edge> adj[MAXN]; Qry qry[MAXN]; int ans[MAXN]; Edge p[MAXL][MAXN]; int lvl[MAXN]; void dfs(int u) { REP (k, 1, MAXL) { if (p[k - 1][u].v == -1 || p[k - 1][p[k - 1][u].v].v == -1) { p[k][u] = {-1, -1, -1, 0, 0}; } else { p[k][u] = p[k - 1][u] + p[k - 1][p[k - 1][u].v]; } } for (Edge e : adj[u]) { if (e.v == p[0][u].v) { continue; } lvl[e.v] = lvl[u] + 1; p[0][e.v] = {u, e.lo, e.hi, 1, 1}; dfs(e.v); } } int sub[MAXN], cp[MAXN]; Edge pth[MAXL][MAXN]; vii ev[MAXN]; void getst(int u, int p, int l) { sub[u] = 1; for (Edge e : adj[u]) { if (e.v == p || lvl[e.v] != -1) { continue; } if (l > 0) { pth[l - 1][e.v] = e + pth[l - 1][u]; } getst(e.v, u, l); sub[u] += sub[e.v]; } } int getcent(int u, int p, int s) { for (Edge e : adj[u]) { if (e.v == p || lvl[e.v] != -1) { continue; } if (sub[e.v] > s / 2) { return getcent(e.v, u, s); } } return u; } void build(int u, int p, int l) { getst(u, -1, l); int cent = getcent(u, -1, sub[u]); cp[cent] = p; lvl[cent] = l; for (Edge e : adj[cent]) { if (e.v == p || lvl[e.v] != -1) { continue; } pth[l][e.v] = e; build(e.v, cent, l + 1); } } int st[MAXN * 40], lc[MAXN * 40], rc[MAXN * 40], ptr; void incre(int p, int x, int u, int lo = 1, int hi = n + k) { if (lo == hi) { st[u] += x; return; } int mid = lo + hi >> 1; if (p <= mid) { if (lc[u] == 0) { lc[u] = ptr++; } incre(p, x, lc[u], lo, mid); } else { if (rc[u] == 0) { rc[u] = ptr++; } incre(p, x, rc[u], mid + 1, hi); } st[u] = st[lc[u]] + st[rc[u]]; } int qsm(int s, int e, int u, int lo = 1, int hi = n + k) { if (lo >= s && hi <= e) { return st[u]; } int mid = lo + hi >> 1; int res = 0; if (s <= mid) { res += qsm(s, e, lc[u], lo, mid); } if (e > mid) { res += qsm(s, e, rc[u], mid + 1, hi); } return res; } int main() { #ifndef DEBUG ios::sync_with_stdio(0), cin.tie(0); #endif cin >> n >> k; REP (i, 1, n + k) { char t; cin >> t; if (t == 'S') { int a, b; cin >> a >> b; adj[a].pb({b, i, i, 1, 1}); adj[b].pb({a, i, i, 1, 1}); qry[i] = {t, a, b}; } else if (t == 'Q') { int a, b; cin >> a >> b; qry[i] = {t, a, b}; } else { int a; cin >> a; qry[i] = {t, a, -1}; } } REP (k, 0, MAXL) { p[k][1] = {-1, -1, -1, 0, 0}; } dfs(1); REP (i, 1, n + k) { auto [t, a, b] = qry[i]; if (t == 'S') { } else if (t == 'Q') { if (a == b) { ans[i] = 1; continue; } Edge lft = {-1, -1, -1, 0, 0}, rht = {-1, -1, -1, 0, 0}; bool swp = 0; if (lvl[a] < lvl[b]) { swap(a, b); swp = 1; } RREP (k, MAXL - 1, 0) { if (p[k][a].v != -1 && lvl[p[k][a].v] >= lvl[b]) { lft = lft + p[k][a]; a = p[k][a].v; } } if (a != b) { RREP (k, MAXL - 1, 0) { if (p[k][a].v != p[k][b].v) { lft = lft + p[k][a]; a = p[k][a].v; rht = rht + p[k][b]; b = p[k][b].v; } } lft = lft + p[0][a]; a = p[0][a].v; rht = rht + p[0][b]; b = p[0][b].v; } assert(a == b); if (swp) { swap(lft, rht); swap(a, b); } Edge res = rht + ~lft; if (res.inc && res.hi <= i) { ans[i] = 1; } else { ans[i] = 0; } } else { } } memset(lvl, -1, sizeof lvl); build(1, -1, 0); ptr = n + 1; REP (i, 1, n + 1) { int a = i; cerr << i << '\n'; ev[0].pb({n + k, i}); RREP (j, lvl[i] - 1, 0) { a = cp[a]; if (pth[j][i].dec) { ev[pth[j][i].lo].pb({pth[j][i].hi, a}); cerr << ' ' << a << ' ' << pth[j][i].lo << ' ' << pth[j][i].hi << '\n'; } } assert(cp[a] == -1); } REP (i, 0, n + k) { auto [t, a, b] = qry[i]; if (i == 0 || t == 'S') { for (auto [x, y] : ev[i]) { incre(x, 1, y); } } else if (t == 'Q') { } else { cerr << a << '\n'; ans[i] = st[a]; cerr << ' ' << st[a] << '\n'; int u = a; RREP (l, lvl[a] - 1, 0) { u = cp[u]; Edge e = pth[l][a]; if (e.inc && e.hi <= i) { int tmp = qsm(e.hi + 1, n + k, u); ans[i] += tmp; cerr << ' ' << u << ' ' << e.hi << ' ' << tmp << '\n'; } } assert(cp[u] == -1); } } REP (i, 1, n + k) { auto [t, a, b] = qry[i]; if (t == 'S') { } else if (t == 'Q') { if (ans[i]) { cout << "yes\n"; } else { cout << "no\n"; } } else { cout << ans[i] << '\n'; } } return 0; }

Compilation message (stderr)

servers.cpp: In function 'void incre(int, int, int, int, int)':
servers.cpp:142:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  142 |     int mid = lo + hi >> 1;
      |               ~~~^~~~
servers.cpp: In function 'int qsm(int, int, int, int, int)':
servers.cpp:160:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  160 |     int mid = lo + hi >> 1;
      |               ~~~^~~~
#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...