제출 #669318

#제출 시각아이디문제언어결과실행 시간메모리
669318baojiaopisuInside information (BOI21_servers)C++14
2.50 / 100
289 ms86052 KiB
#include<bits/stdc++.h> using namespace std; using ll = long long; using ld = long double; using ull = unsigned long long; using pii = pair<int, int>; using pll = pair<ll, ll>; using pld = pair<ld, ld>; #define fi first #define se second #define left BAO #define right ANH #define pb push_back #define pf push_front #define mp make_pair #define ins insert #define btpc __builtin_popcount #define btclz __builtin_clz #define sz(x) (int)(x.size()); #define all(x) x.begin(), x.end() #define debug(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); int d4x[4] = {1, 0, -1, 0}; int d4y[4] = {0, 1, 0, -1}; int d8x[8] = {0, 1, 1, 1, 0, -1, -1, -1}; int d8y[8] = {1, 1, 0, -1, -1, -1, 0, 1}; template<class X, class Y> bool minimize(X &x, const Y &y) { if (x > y) { x = y; return true; } return false; } template<class X, class Y> bool maximize(X &x, const Y &y) { if (x < y) { x = y; return true; } return false; } const int MOD = 1e9 + 7; //998244353 template<class X, class Y> void add(X &x, const Y &y) { x = (x + y); if(x >= MOD) x -= MOD; } template<class X, class Y> void sub(X &x, const Y &y) { x = (x - y); if(x < 0) x += MOD; } /* Author : Le Ngoc Bao Anh, 12A5, LQD High School for Gifted Student*/ const ll INF = 1e9; const int N = 2e5 + 10; const int LOG = 17; vector<pii> g[N]; pii par[N]; int depth[N], in[N], de[N], l[N], r[N], sz[N]; int cpar[N], cdepth[N]; int res[N]; bool visited[N]; int f[N][LOG + 2], cnt[N]; vector<int> upd[N]; int Time = 0; template <class T> struct FenwickTree { int n; vector<T> bit; FenwickTree(int _n = 0) { n = _n; bit.resize(n + 5); for(int i = 1; i <= n; i++) bit[i] = 0; } void update(int pos, T x) { for(int i = pos; i <= n; i += i & (-i)) bit[i] += x; } T get(int pos) { T ans = 0; for(int i = pos; i > 0; i -= i & (-i)) ans += bit[i]; return ans; } }; FenwickTree<int> BIT; struct Queries { int type, u, v, id; }; vector<Queries> queries; struct Edges { int u, v, w; }; vector<Edges> ed; struct P { int u, id, idq; }; vector<P> path; void dfs(int u) { l[u] = ++Time; for(auto nxt : g[u]) { int v = nxt.fi; int w = nxt.se; if(v != par[u].fi) { par[v] = mp(u, w); depth[v] = depth[u] + 1; if(u == 1) { in[v] = de[v] = u; } else { in[v] = (w < par[u].se ? in[u] : u); de[v] = (w > par[u].se ? de[u] : u); } dfs(v); } } r[u] = Time; } int find_lca(int u, int v) { if(depth[u] < depth[v]) swap(u, v); for(int i = LOG; i >= 0; i--) { if(depth[u] - (1 << i) >= depth[v]) u = f[u][i]; } if(u == v) return u; for(int i = LOG; i >= 0; i--) { if(f[u][i] != f[v][i]) { u = f[u][i]; v = f[v][i]; } } return f[u][0]; } int find_par(int u, int d) { for(int i = LOG; i >= 0; i--) { if(depth[u] - (1 << i) >= d) u = f[u][i]; } return u; } bool can_go(int u, int v, int id) { int p = find_lca(u, v); if(u == v) return true; bool ok = (depth[in[u]] <= depth[p] && depth[de[v]] <= depth[p]); int prv; if(v == p) { prv = find_par(u, depth[p] + 1); ok &= (par[prv].se <= id); } else ok &= (par[v].se <= id); if(u != p && v != p) { u = find_par(u, depth[p] + 1); v = find_par(v, depth[p] + 1); ok &= (par[u].se <= par[v].se); } return ok; } void dfs_sz(int u, int par) { sz[u] = 1; for(auto nxt : g[u]) { int v = nxt.fi; int w = nxt.se; if(!visited[v] && v != par) { dfs_sz(v, u); sz[u] += sz[v]; } } } int centroid(int u, int par, int n) { for(auto nxt : g[u]) { int v = nxt.fi; if(v != par && !visited[v] && sz[v] * 2 > n) return centroid(v, u, n); } return u; } int build_centroid(int u) { dfs_sz(u, 0); u = centroid(u, 0, sz[u]); visited[u] = true; for(auto nxt : g[u]) { int v = nxt.fi; if(!visited[v]) { int x = build_centroid(v); cdepth[x] = cdepth[u] + 1; cpar[x] = u; } } return u; } int first_edge(int u, int v) { if(u == v) return INF; if(l[u] <= l[v] && r[v] <= r[u]) { int p = find_par(v, depth[u] + 1); return par[p].se; } return par[u].se; } int last_edge(int u, int v) { if(u == v) return 0; if(l[v] <= l[u] && r[u] <= r[v]) { int p = find_par(u, depth[v] + 1); return par[p].se; } return par[v].se; } void BaoJiaoPisu() { int n, q; cin >> n >> q; q += n - 1; for(int i = 1; i <= q; i++) { char c; cin >> c; if(c == 'S') { int u, v; cin >> u >> v; g[u].pb(mp(v, i)); g[v].pb(mp(u, i)); ed.pb({u, v, i}); } if(c == 'Q') { int a, b; cin >> a >> b; queries.pb({0, a, b, i}); } if(c == 'C') { int a; cin >> a; queries.pb({1, a, 0, i}); } } depth[1] = 1; dfs(1); for(int i = 1; i <= n; i++) f[i][0] = par[i].fi; for(int j = 1; j <= LOG; j++) { for(int i = 1; i <= n; i++) { if(depth[i] <= (1 << j)) continue; int u = f[i][j - 1]; f[i][j] = f[u][j - 1]; } } de[1] = in[1] = 1; build_centroid(1); for(int i = 0; i < queries.size(); i++) { if(!queries[i].type) { int id = queries[i].id; int u = queries[i].v, v = queries[i].u; res[i] = can_go(u, v, id); } else { int id = queries[i].id; int u = queries[i].u; int v = u; while(v) { if(can_go(u, v, id) && last_edge(u, v) <= id) path.pb({v, last_edge(u, v) + 1, i}); v = cpar[v]; } } } sort(all(path), [&](P x, P y) { return x.id > y.id; }); for(int i = 1; i <= n; i++) cnt[i]++; for(int i = 1; i <= n; i++) { int u = i, v = cpar[i]; while(v) { if(can_go(v, u, INF)) { upd[first_edge(v, u)].pb(v); } v = cpar[v]; } } int iter = ed.size() - 1; for(int i = 0; i < path.size(); i++) { int id = path[i].id; while(iter >= 0 && ed[iter].w >= id) { int w = ed[iter].w; for(auto u : upd[w]) ++cnt[u]; iter--; } int idq = path[i].idq; int u = path[i].u; res[idq] += cnt[u]; } for(int i = 0; i < queries.size(); i++) { if(!queries[i].type) { cout << (res[i] ? "yes" : "no") << '\n'; } else cout << res[i] << '\n'; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int tc = 1, ddd = 0; // cin >> tc; while(tc--) { //ddd++; //cout << "Case #" << ddd << ": "; BaoJiaoPisu(); } }

컴파일 시 표준 에러 (stderr) 메시지

servers.cpp: In function 'void dfs_sz(int, int)':
servers.cpp:193:7: warning: unused variable 'w' [-Wunused-variable]
  193 |   int w = nxt.se;
      |       ^
servers.cpp: In function 'void BaoJiaoPisu()':
servers.cpp:287:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Queries>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  287 |  for(int i = 0; i < queries.size(); i++) {
      |                 ~~^~~~~~~~~~~~~~~~
servers.cpp:322:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<P>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  322 |  for(int i = 0; i < path.size(); i++) {
      |                 ~~^~~~~~~~~~~~~
servers.cpp:335:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Queries>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  335 |  for(int i = 0; i < queries.size(); i++) {
      |                 ~~^~~~~~~~~~~~~~~~
servers.cpp: In function 'int main()':
servers.cpp:346:17: warning: unused variable 'ddd' [-Wunused-variable]
  346 |     int tc = 1, ddd = 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...