Submission #1295887

#TimeUsernameProblemLanguageResultExecution timeMemory
1295887ducanh0811Traffickers (RMI18_traffickers)C++20
0 / 100
349 ms589824 KiB
#include <bits/stdc++.h> #define int long long #define FOR(i, a, b) for (int i = (a), _b = (b); i <= _b; ++i) using namespace std; #define MAXN 30005 int n, k, q; vector<int> g[MAXN]; struct node { int sum; int lz; node(int _sum = 0, int _lz = 0) { sum = _sum; lz = _lz; } }; node combine(const node &a, const node &b) { node res = node(); res.sum = a.sum + b.sum; return res; } struct SMT { int n; vector<node> st; SMT(int _n = 0) { n = _n; st.assign((n << 2) + 5, node()); } void pushDown(int id, int l, int r, int mid) { if (st[id].lz == 0) return; st[id << 1].sum += st[id].lz * (mid - l + 1); st[id << 1].lz += st[id].lz; st[id << 1 | 1].sum += st[id].lz * (r - mid); st[id << 1 | 1].lz += st[id].lz; st[id].lz = 0; } void upd(int id, int l, int r, int u, int v, int val) { if (v < l || r < u) return; if (u <= l && r <= v) { st[id].sum += val * (r - l + 1); st[id].lz += val; return; } int mid = (l + r) >> 1; pushDown(id, l, r, mid); upd(id << 1, l, mid, u, v, val); upd(id << 1 | 1, mid + 1, r, u, v, val); st[id] = combine(st[id << 1], st[id << 1 | 1]); } void upd(int u, int v, int val) { upd(1, 1, n, u, v, val); } node get(int id, int l, int r, int u, int v) { if (v < l || r < u) return node(); if (u <= l && r <= v) return st[id]; int mid = (l + r) >> 1; pushDown(id, l, r, mid); return combine(get(id << 1, l, mid, u, v), get(id << 1 | 1, mid + 1, r, u, v)); } int get(int u, int v) { return get(1, 1, n, u, v).sum; } } tree[22][22]; int child[MAXN], par[MAXN], heavy[MAXN], dep[MAXN]; int pos[MAXN], head[MAXN], timer = 0; void dfs(int u, int p) { child[u] = 1; int mx_c = 0; for (int &v : g[u]) { if (v == p) continue; dep[v] = dep[u] + 1; par[v] = u; dfs(v, u); child[u] += child[v]; if (child[v] > mx_c) { mx_c = child[v]; heavy[u] = v; } } } void hld(int u, int h) { head[u] = h; pos[u] = ++timer; if (heavy[u] != 0) hld(heavy[u], h); for (int &v : g[u]) { if (v == par[u] || v == heavy[u]) continue; hld(v, v); } } int LCA(int u, int v) { while (head[u] != head[v]) { if (dep[head[u]] < dep[head[v]]) swap(u, v); u = par[head[u]]; } if (dep[u] > dep[v]) swap(u, v); return u; } void upd(int u, int v, int val, int id, int length) { while (head[u] != head[v]) { if (dep[head[u]] < dep[head[v]]) swap(u, v); tree[length][id].upd(pos[head[u]], pos[u], val); u = par[head[u]]; } if (pos[u] > pos[v]) swap(u, v); tree[length][id].upd(pos[u], pos[v], val); } int query(int u, int v, int id, int length) { int res = 0; while (head[u] != head[v]) { if (dep[head[u]] < dep[head[v]]) swap(u, v); res += tree[length][id].get(pos[head[u]], pos[u]); u = par[head[u]]; } if (pos[u] > pos[v]) swap(u, v); res += tree[length][id].get(pos[u], pos[v]); return res; } void modifyPath(int sta, int fin, int delta) { int mid = LCA(sta, fin); int numNode = dep[sta] + dep[fin] - 2 * dep[mid] + 1; vector<int> up, down; while (sta != mid) { up.push_back(sta); sta = par[sta]; } while (fin != mid) { down.push_back(fin); fin = par[fin]; } reverse(down.begin(), down.end()); vector<int> nodes; nodes.insert(nodes.end(), up.begin(), up.end()); nodes.push_back(mid); nodes.insert(nodes.end(), down.begin(), down.end()); FOR(i, 0, nodes.size() - 1) { upd(nodes[0], nodes[i], delta, i, numNode); } } int cost(int t1, int t2, int numNode, int a, int b) { int res = query(a, b, 0, numNode); int t = t2 - t1; int fullCount = t / numNode; res += query(a, b, numNode - 1, numNode) * fullCount; t1 %= numNode; t2 %= numNode; if (t1 <= t2) { res += query(a, b, t2, numNode); res -= query(a, b, t1, numNode); } else { res += query(a, b, numNode - 1, numNode); res -= query(a, b, t1, numNode); res += query(a, b, t2, numNode); } return res; } void solve() { cin >> n; FOR(i, 1, n - 1) { int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } FOR(i, 0, 20) FOR(j, 0, 20) tree[i][j] = SMT(n); dfs(1, 0); hld(1, 1); cin >> k; FOR(i, 1, k) { int x, y; cin >> x >> y; modifyPath(x, y, 1); } cin >> q; FOR(i, 1, q) { int type, a, b; cin >> type >> a >> b; if (type == 1) modifyPath(a, b, 1); else if (type == 2) modifyPath(a, b, -1); else if (type == 3) { int t1, t2; cin >> t1 >> t2; int res = 0; FOR(numNode, 1, 20) { res += cost(t1, t2, numNode, a, b); } cout << res << '\n'; } } } #define task "test" int32_t main() { if (fopen(task".inp","r")) { freopen(task".inp","r",stdin); freopen(task".out","w",stdout); } ios_base::sync_with_stdio(false); cin.tie(NULL); solve(); return 0; }

Compilation message (stderr)

traffickers.cpp: In function 'int32_t main()':
traffickers.cpp:206:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  206 |         freopen(task".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
traffickers.cpp:207:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  207 |         freopen(task".out","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...