제출 #1098944

#제출 시각아이디문제언어결과실행 시간메모리
1098944steveonalexDynamic Diameter (CEOI19_diameter)C++17
100 / 100
578 ms71088 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define MASK(i) (1LL << (i)) #define GETBIT(mask, i) (((mask) >> (i)) & 1) #define ALL(v) (v).begin(), (v).end() #define block_of_code if(true) ll max(ll a, ll b){return (a > b) ? a : b;} ll min(ll a, ll b){return (a < b) ? a : b;} ll gcd(ll a, ll b){return __gcd(a, b);} ll lcm(ll a, ll b){return a / gcd(a, b) * b;} ll LASTBIT(ll mask){return (mask) & (-mask);} int pop_cnt(ll mask){return __builtin_popcountll(mask);} int ctz(ull mask){return __builtin_ctzll(mask);} int logOf(ull mask){return 63 - __builtin_clzll(mask);} mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);} double rngesus_d(double l, double r){ double cur = rngesus(0, MASK(60) - 1); cur /= MASK(60) - 1; return l + cur * (r - l); } template <class T1, class T2> bool maximize(T1 &a, T2 b){ if (a < b) {a = b; return true;} return false; } template <class T1, class T2> bool minimize(T1 &a, T2 b){ if (a > b) {a = b; return true;} return false; } template <class T> void printArr(T container, string separator = " ", string finish = "\n", ostream &out = cout){ for(auto item: container) out << item << separator; out << finish; } template <class T> void remove_dup(vector<T> &a){ sort(ALL(a)); a.resize(unique(ALL(a)) - a.begin()); } const ll N = 1e5 + 69, LOG_N = 17, BLOCK = 600; ll n, q; vector<pair<ll, ll>> graph[N]; ll w[N]; ll parent[N]; ll l[N], r[N], pos[N * 2], dfs_cnt = 0, rmq[LOG_N + 1][N * 2]; void init_lca(ll u, ll p){ l[u] = r[u] = ++dfs_cnt; rmq[0][dfs_cnt] = l[u]; pos[dfs_cnt] = u; for(pair<ll,ll> v: graph[u]) if (v.first != p){ parent[v.second] = v.first; init_lca(v.first, u); r[u] = ++dfs_cnt; rmq[0][dfs_cnt] = l[u]; pos[dfs_cnt] = u; } } void init_rmq(){ for(ll j = 1; MASK(j) <= n * 2 - 1; ++j) for(ll i = 1; i + MASK(j) - 1 <= n * 2 - 1; ++i){ rmq[j][i] = min(rmq[j-1][i], rmq[j-1][i + MASK(j-1)]); } } ll LCA(ll u, ll v){ u = l[u], v = l[v]; if (u > v) swap(u, v); ll j = logOf(v - u + 1); return pos[min(rmq[j][u], rmq[j][v - MASK(j) + 1])]; } ll h[N * 2], s_h[N * 2 / BLOCK + 1]; void update_h(ll l, ll r, ll v){ ll b_l = l / BLOCK, b_r = r / BLOCK; if (b_l == b_r){ for(ll i = l; i <= r; ++i) h[i] += v; } else{ for(ll i = l; i < (b_l + 1) * BLOCK; ++i) h[i] += v; for(ll i = b_r * BLOCK; i <= r; ++i) h[i] += v; for(ll i = b_l + 1; i <= b_r - 1; ++i) s_h[i] += v; } } ll get_h(ll i){ i = l[i]; return h[i] + s_h[i / BLOCK]; } ll get_sum_path(ll u, ll v){ return get_h(u) + get_h(v) - 2 * get_h(LCA(u, v)); } struct SegmentTree{ struct Node{ ll u, v; ll w; Node(ll u = 0, ll v = 0, ll w = 0): u(u), v(v), w(w){ } bool operator < (Node x) const { return w < x.w; } bool operator > (Node x) const { return w > x.w; } }; Node combine(Node a, Node b){ if (a.u == 0) return b; if (b.u == 0) return a; Node ans = max(a, b); for(ll i = 0; i <= 1; ++i) { for(ll j = 0; j <= 1; ++j){ Node cur = Node(a.u, b.u, get_sum_path(a.u, b.u)); maximize(ans, cur); swap(b.u, b.v); } swap(a.u, a.v); } return ans; } ll n; vector<Node> a; SegmentTree(ll _n){ n = _n; a.resize(n * 4 + 4, Node()); build_tree(1, n, 1); } void build_tree(ll l, ll r, ll id){ if (l == r) {a[id] = Node(pos[l], pos[l], 0); return;} ll mid = (l + r) >> 1; build_tree(l, mid, id * 2); build_tree(mid + 1, r, id * 2 + 1); a[id] = combine(a[id * 2], a[id * 2 + 1]); } void update(ll u, ll v, ll l, ll r, ll id){ if (u <= l && r <= v) return; ll mid = (l + r) >> 1; if (u <= mid) update(u, v, l, mid, id * 2); if (v > mid) update(u, v, mid + 1, r, id * 2 + 1); a[id] = combine(a[id * 2], a[id * 2 + 1]); } void update(ll l, ll r){update(l, r, 1, n, 1);} ll get(){return a[1].w;} }; int main(void){ ios::sync_with_stdio(0);cin.tie(0); cout.tie(0); clock_t start = clock(); cin >> n >> q >> w[0]; for(int i= 1; i<n; ++i){ int u, v; cin >> u >> v >> w[i]; graph[u].push_back({v, i}); graph[v].push_back({u, i}); } init_lca(1, 0); init_rmq(); for(int i = 1; i<n; ++i) { int u = parent[i]; update_h(l[u], r[u], w[i]); } SegmentTree st(n * 2 - 1); ll last = 0; for(int it = 0; it < q; ++it){ ll d, e; cin >> d >> e; d = (d + last) % (n-1) + 1; e = (e + last) % w[0]; int u = parent[d]; ll diff = e - w[d]; w[d] = e; update_h(l[u], r[u], diff); st.update(l[u], r[u]); last = st.get(); cout << last << "\n"; } cerr << "Time elapsed: " << clock() - start << " ms\n"; return 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...