Submission #226945

#TimeUsernameProblemLanguageResultExecution timeMemory
226945qkxwsmTraffickers (RMI18_traffickers)C++14
100 / 100
1639 ms58100 KiB
#include <bits/stdc++.h> using namespace std; template<class T, class U> void ckmin(T &a, U b) { if (a > b) a = b; } template<class T, class U> void ckmax(T &a, U b) { if (a < b) a = b; } #define MP make_pair #define PB push_back #define LB lower_bound #define UB upper_bound #define fi first #define se second #define SZ(x) ((int) (x).size()) #define ALL(x) (x).begin(), (x).end() #define FOR(i, a, b) for (auto i = (a); i < (b); i++) #define FORD(i, a, b) for (auto i = (a) - 1; i >= (b); i--) typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef vector<int> vi; typedef vector<ll> vl; typedef vector<pii> vpi; typedef vector<pll> vpl; const int MAXN = 30013; int N, K, Q, T; vi edge[MAXN]; ll fen[23][23][MAXN]; vi ord; int parent[MAXN], st[MAXN], depth[MAXN], st1[MAXN], ft1[MAXN]; int table[20][2 * MAXN]; int comb(int u, int v) { return (depth[u] > depth[v] ? v : u); } ll query(int l, int r) { int sz = 31 - __builtin_clz(r - l + 1); return comb(table[sz][l], table[sz][r - (1 << sz) + 1]); } void dfs(int u, int p) { ord.PB(u); st[u] = SZ(ord) - 1; st1[u] = T; ft1[u] = T; T++; for (int v : edge[u]) { if (v == p) continue; parent[v] = u; depth[v] = depth[u] + 1; dfs(v, u); ord.PB(u); ft1[u] = ft1[v]; } } int lca(int u, int v) { u = st[u], v = st[v]; if (u > v) swap(u, v); return query(u, v); } void update(int f, int g, int idx, int v) { for (int e = idx + 1; e <= N; e += e & (-e)) { fen[f][g][e] += v; } } ll query(int f, int g, int idx) { ll res = 0; for (int e = idx + 1; e; e -= e & (-e)) { res += fen[f][g][e]; } return res; } vi getpath(int u, int v) { int w = lca(u, v); vi path, path1; int x = u; while(x != w) { path.PB(x); x = parent[x]; } x = v; while(x != w) { path1.PB(x); x = parent[x]; } reverse(ALL(path1)); path.PB(w); path.insert(path.end(), ALL(path1)); return path; } void work(int u, int v, int f) { vi path = getpath(u, v); //we have the path from u to v int m = SZ(path); FOR(i, 0, SZ(path)) { int w = path[i]; update(m, i, st1[w], f); update(m, i, ft1[w] + 1, -f); } return; } ll cntmod(ll x, int a, int b) { if (x < a) return 0; //how many numbers in 0...x are a modulo b? x -= a; return (x / b) + 1; } int32_t main() { cout << fixed << setprecision(12); cerr << fixed << setprecision(4); ios_base::sync_with_stdio(false); cin.tie(0); // cerr << "?" << cntmod(0, 1, 20) << endl; cin >> N; FOR(i, 0, N - 1) { int u, v; cin >> u >> v; u--; v--; edge[u].PB(v); edge[v].PB(u); } parent[0] = N; dfs(0, N); FOR(i, 0, SZ(ord)) { table[0][i] = ord[i]; } FOR(i, 1, 20) { FOR(j, 0, SZ(ord) - (1 << i) + 1) { table[i][j] = comb(table[i - 1][j], table[i - 1][j + (1 << (i - 1))]); } } cin >> K; FOR(i, 0, K) { int u, v; cin >> u >> v; u--; v--; work(u, v, 1); } cin >> Q; while(Q--) { int qid, u, v; cin >> qid >> u >> v; u--; v--; if (qid == 1) { work(u, v, 1); } if (qid == 2) { work(u, v, -1); } if (qid == 3) { ll l, r; cin >> l >> r; ll ans = 0; int w = lca(u, v); FOR(i, 1, 22) { // cerr << "i = " << i << endl; FOR(j, 0, i) { // cerr << "j = " << j << endl; //j mod i //how many numbers in [l...r] are j mod i? ll cur = 0, co = cntmod(r, j, i) - cntmod(l - 1, j, i); cur += query(i, j, st1[u]); cur += query(i, j, st1[v]); cur -= query(i, j, st1[w]); if (w != 0) cur -= query(i, j, st1[parent[w]]); ans += cur * co; // cerr << "co = " << co << endl; // cerr << j << ' ' << i << ' ' << co << endl; } } cout << ans << '\n'; } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...