Submission #1234217

#TimeUsernameProblemLanguageResultExecution timeMemory
1234217g4yuhgDynamic Diameter (CEOI19_diameter)C++20
100 / 100
1028 ms60996 KiB
//Huyduocdithitp #include <bits/stdc++.h> typedef long long ll; #define int long long #define endl '\n' #define yes cout<<"YES"<<endl; #define no cout<<"NO"<<endl; #define fi first #define se second #define pii pair<ll, ll> #define inf 1000000000000000000LL #define faster ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); #define MP make_pair #define TASK "ghuy4g" #define start if(fopen(TASK".inp","r")){freopen(TASK".inp","r",stdin);freopen(TASK".out","w",stdout);} #define LOG 19 #define N 100005 using namespace std; bool ghuy4g; ll S = 317; struct Canh { int u, v; long long w; } canh[N]; ll n, t, q, w; vector<pii> adj[N]; int st[LOG + 2][2 * N], L[N], R[N], id[N]; int in[N], tour[N], high[N], par[N], out[N], timeDfs; vector<ll> euler, depth, first; ll d[N], lazy[N]; void dfs(ll u, ll parent, ll di) { in[u] = ++ timeDfs; tour[timeDfs] = u; first[u] = euler.size(); euler.push_back(u); depth.push_back(di); for (auto v : adj[u]) { if (v.fi == parent) continue; par[v.fi] = u; dfs(v.fi, u, di + 1); euler.push_back(u); depth.push_back(di); } out[u] = timeDfs; } void build_sparse_table() { ll m = depth.size(); for (ll i = 0; i < m; ++i) { st[0][i] = i; // store index in depth[] } for (ll k = 1; (1 << k) <= m; ++k) { for (ll i = 0; i + (1 << k) <= m; ++i) { ll x = st[k - 1][i]; ll y = st[k - 1][i + (1 << (k - 1))]; st[k][i] = (depth[x] < depth[y] ? x : y); } } } ll get_min_index(ll l, ll r) { ll len = r - l + 1; ll k = 31 - __builtin_clz(len); // floor(log2(len)) ll x = st[k][l]; ll y = st[k][r - (1 << k) + 1]; return (depth[x] < depth[y] ? x : y); } ll lca(ll u, ll v) { ll l = first[u]; ll r = first[v]; if (l > r) swap(l, r); ll idx_in_depth = get_min_index(l, r); return euler[idx_in_depth]; } ll query(ll u) { return d[ in[u] ] + lazy[ id[ in[u] ] ]; } ll dis(ll u, ll v) { ll x = lca(u, v); return query(u) + query(v) - 2 * query(x); } struct Node { int u, v; long long len; } ST[4 * N]; Node combine(Node A, Node B) { Node res = {0, 0, -inf}; ll d; d = dis(A.u, A.v); if (d > res.len) res = {A.u, A.v, d}; d = dis(A.u, B.u); if (d > res.len) res = {A.u, B.u, d}; d = dis(A.u, B.v); if (d > res.len) res = {A.u, B.v, d}; d = dis(A.v, B.u); if (d > res.len) res = {A.v, B.u, d}; d = dis(A.v, B.v); if (d > res.len) res = {A.v, B.v, d}; d = dis(B.u, B.v); if (d > res.len) res = {B.u, B.v, d}; return res; } void Build(int id, int l, int r) { if (l == r) { ST[id] = {tour[l], tour[l], 0}; return; } int mid = (l + r) >> 1; Build(id<<1, l, mid); Build(id<<1|1, mid+1, r); ST[id] = combine(ST[id<<1], ST[id<<1|1]); } void update1_rec(int id, int l, int r, int pos) { if (l > pos || r < pos) return; if (l == r) { ST[id] = {tour[l], tour[l], 0}; return; } int mid = (l + r) >> 1; if (pos <= mid) update1_rec(id<<1, l, mid, pos); else update1_rec(id<<1|1, mid+1, r, pos); ST[id] = combine(ST[id<<1], ST[id<<1|1]); } void update1(int pos) { update1_rec(1, 1, n, pos); } bool flag = 0; void upd_sqrt(ll u, ll w) { // update subtree u them w ;// mang d la tinh theo tour, khi get ta lay d[tour[u]] voi u la dinh // in[u] -> out[u] // for tu in[u] -> cuoi block in[u] if (flag) { cout << u << " " << w << " " << in[u] << " " << out[u] << endl; } if (id[in[u]] == id[out[u]]) { for (int i = in[u]; i <= out[u]; i ++) { if (flag) cout << "trau cong0 " << i << " " << w << endl; d[i] += w; } return; } for (int i = in[u]; i <= R[id[in[u]]]; i ++) { //cout << "trau cong1 " << i << " " << w << endl; d[i] += w; } for (int i = L[id[out[u]]]; i <= out[u]; i ++) { //cout << "trau cong2 " << i << " " << w << endl; d[i] += w; } for (int i = id[in[u]] + 1; i <= id[out[u]] - 1; i ++) { //cout << "lazy cong " << i << " " << w << endl; lazy[i] += w; } } void upd(int i, ll val) { int u = canh[i].u, v = canh[i].v; if (par[u] == v) swap(u, v); upd_sqrt(v, val - canh[i].w); canh[i].w = val; //cout << v << endl; //cout << query(7) << endl; if (par[v] == u) swap(u, v); // u la con update1(in[u]); update1(in[u] - 1); update1(out[u]); update1(out[u] + 1); } void pre() { first.resize(n + 1); dfs(1, -1, 0); build_sparse_table(); // prepare for chia can for (int i = 1; i <= n; i ++) { id[i] = (i - 1) / S + 1; if (L[id[i]] == 0) L[id[i]] = i; R[id[i]] = i; //cout << i << " " << in[i] << " " << out[i] << endl; } //cout << lca(2, 8) << endl; for (int i = 1; i <= n - 1; i ++) { ll u = canh[i].u, v = canh[i].v, w = canh[i].w; if (u == par[v]) swap(u, v); upd_sqrt(u, w); //cout << u << " uw " << w << endl; } Build(1, 1, n); //cout << query(1, 3) << endl; //cout << ST[1].len << endl; //cout << query(2) << endl; //cout << query(3) << endl; //cout << query(1) << endl; //exit(0); } void solve() { ll last = 0; for (int i = 1; i <= q; i ++) { ll d, e; cin >> d >> e; d = (d + last) % (n - 1); e = (e + last) % w; d ++ ; if (i == 97) { //cout << last << " " << d << " " << e << " " << canh[d].w << endl; //flag = 1; } upd(d, e); cout << ST[1].len << endl; last = ST[1].len; flag = 0; } } bool klinh; signed main(void) { faster; cin >> n >> q >> w; for (int i = 1; i <= n - 1; i ++) { ll u, v, w; cin >> u >> v >> w; canh[i] = {u, v, w}; adj[u].push_back({v, w}); adj[v].push_back({u, w}); } pre(); solve(); cerr << fabs(&klinh - &ghuy4g) / 1048576.0; 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...