Submission #1295862

#TimeUsernameProblemLanguageResultExecution timeMemory
1295862MinhKienTraffickers (RMI18_traffickers)C++20
100 / 100
714 ms29252 KiB
#include <iostream> #include <vector> using namespace std; const int N = 3e4 + 10; int n, x, y; int q, type, t1, t2; int sz[N], ChainID[N], ChainHead[N]; int in[N], out[N], par[N]; int CurChain = 1, CurPos; vector <int> v[N]; int calc_size(int s = 1, int p = -1) { sz[s] = 1; for (int z: v[s]) { if (z == p) continue; par[z] = s; sz[s] += calc_size(z, s); } return sz[s]; } void HLD(int s = 1) { if (!ChainHead[CurChain]) { ChainHead[CurChain] = s; } ChainID[s] = CurChain; in[s] = out[s] = ++CurPos; int nxt = 0; for (int z: v[s]) { if (z == par[s]) continue; if (sz[z] > sz[nxt]) nxt = z; } if (!nxt) return; HLD(nxt); out[s] = out[nxt]; for (int z: v[s]) { if (z == par[s] || nxt == z) continue; ++CurChain; HLD(z); out[s] = out[z]; } } struct BIT { int val[N]; BIT () { fill_n(val, N, 0); } void update(int u, int VAL) { while (u <= n) { val[u] += VAL; u += u & -u; } } int get(int u) { int res = 0; while (u > 0) { res += val[u]; u -= u & -u; } return res; } int range(int l, int r) { return get(r) - get(l - 1); } }; vector <BIT> bit[21]; void UPDATE(int A, int B, int val) { vector <int> one, two; while (!(in[A] <= in[B] && out[A] >= in[B])) { one.push_back(A); A = par[A]; } one.push_back(A); while (B != A) { two.push_back(B); B = par[B]; } while (!two.empty()) { one.push_back(two.back()); two.pop_back(); } int len = one.size(); for (int i = 0; i < len; ++i) { bit[len][i].update(in[one[i]], val); } } int GetPath(int A, int B, int len, int mod) { int res = 0; while (ChainID[A] != ChainID[B]) { if (ChainID[A] < ChainID[B]) swap(A, B); res += bit[len][mod].range(in[ChainHead[ChainID[A]]], in[A]); A = par[ChainHead[ChainID[A]]]; } if (in[A] > in[B]) swap(A, B); res += bit[len][mod].range(in[A], in[B]); return res; } int Left(int l, int num, int mod) { int ret = (int)(l / num) * num + mod; if (ret < l) ret += num; return ret; } int Right(int r, int num, int mod) { int ret = (int)(r / num) * num + mod; if (ret > r) ret -= num; return ret; } int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(false); cin >> n; for (int i = 1; i < n; ++i) { cin >> x >> y; v[x].push_back(y); v[y].push_back(x); } calc_size(); HLD(); for (int i = 1; i <= 20; ++i) { bit[i].resize(i); } cin >> q; while (q--) { cin >> x >> y; UPDATE(x, y, 1); } cin >> q; while (q--) { cin >> type >> x >> y; if (type == 1) UPDATE(x, y, 1); else if (type == 2) UPDATE(x, y, -1); else { cin >> t1 >> t2; long long ans = 0; for (int len = 1; len <= 20; ++len) { for (int mod = 0; mod < len; ++mod) { int LEFT = Left(t1, len, mod), RIGHT = Right(t2, len, mod); if (LEFT > RIGHT) continue; int one = GetPath(x, y, len, mod); int two = (RIGHT - LEFT) / len + 1; ans += 1ll * one * two; } } cout << ans << "\n"; } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...