제출 #609158

#제출 시각아이디문제언어결과실행 시간메모리
609158MohammadAghilDynamic Diameter (CEOI19_diameter)C++17
31 / 100
5080 ms353636 KiB
#include <bits/stdc++.h> #pragma GCC optimize ("Ofast,unroll-loops") #pragma GCC target ("avx2") using namespace std; typedef long long ll; typedef pair<ll, int> pp; #define er(args ...) cerr << __LINE__ << ": ", err(new istringstream(string(#args)), args), cerr << endl #define per(i,r,l) for(int i = (r); i >= (l); i--) #define rep(i,l,r) for(int i = (l); i < (r); i++) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() #define pb push_back #define ss second #define ff first void err(istringstream *iss){}template<typename T,typename ...Args> void err(istringstream *iss,const T &_val, const Args&...args){string _name;*iss>>_name;if(_name.back()==',')_name.pop_back();cerr<<_name<<" = "<<_val<<", ",err(iss,args...);} void IOS(){ cin.tie(0) -> sync_with_stdio(0); // #ifndef ONLINE_JUDGE // freopen("in.in", "r", stdin); // freopen("out.out", "w", stdout); // #endif } mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const ll mod = 1e9 + 7, maxn = 1e5 + 5, lg = 22, inf = ll(1e18) + 5; ll pw(ll a,ll b,ll md=mod){if(!b)return 1;ll k=pw(a,b>>1ll);return k*k%md*(b&1ll?a:1)%md;} struct Segment{ vector<ll> laz, seg; int n; Segment(){} Segment(vector<ll> a): n(sz(a)){ laz.assign(n<<2, 0), seg.assign(n<<2, 0); build(1, 0, n, a); } void build(int x, int lx, int rx, vector<ll>& a){ if(lx + 1 == rx){ seg[x] = a[lx]; return; } int mid = (lx + rx)>>1; build(x<<1, lx, mid, a), build(x<<1|1, mid, rx, a); seg[x] = max(seg[x<<1], seg[x<<1|1]); } void updNode(int x, ll k){ seg[x] += k, laz[x] += k; } void shift(int x){ if(laz[x]){ updNode(x<<1, laz[x]); updNode(x<<1|1, laz[x]); laz[x] = 0; } } void upd(int l, int r, ll k, int x, int lx, int rx){ if(l <= lx && r >= rx){ updNode(x, k); return; } shift(x); int mid = (lx + rx)>>1; if(l < mid) upd(l, r, k, x<<1, lx, mid); if(mid < r) upd(l, r, k, x<<1|1, mid, rx); seg[x] = max(seg[x<<1], seg[x<<1|1]); } void upd(int l, int r, ll k){ upd(l, r, k, 1, 0, n); } ll get(int l, int r, int x, int lx, int rx){ if(l <= lx && r >= rx) return seg[x]; shift(x); int mid = (lx + rx)>>1; ll res = 0; if(l < mid) res = get(l, r, x<<1, lx, mid); if(mid < r) res = max(res, get(l, r, x<<1|1, mid, rx)); return res; } ll get(int l, int r){ return get(l, r, 1, 0, n); } } seg[maxn]; int cnt[maxn], par[maxn]; vector<pair<int, ll>> adj[maxn]; map<int, int> st[maxn], en[maxn], id[maxn]; int t; bool ban[maxn]; set<pp> mx[maxn]; #define chk (c-p&&ban[c]^1) void dfs(int r, int p){ cnt[r] = 1; for(auto[c, d]: adj[r]) if(chk){ dfs(c, r); cnt[r] += cnt[c]; } } int find_center(int r, int p, int tot){ for(auto[c, d]: adj[r]) if(chk && (cnt[c]<<1) > tot) return find_center(c, r, tot); return r; } vector<ll> tmp; void dfs2(int r, int p, int cen, ll dist, int ref){ if(p == cen) ref = r; id[cen][r] = ref; tmp.pb(dist); st[cen][r] = t++; for(auto[c, d]: adj[r]) if(chk) dfs2(c, r, cen, dist + d, ref); en[cen][r] = t; } void reset(int r){ ban[r] = true; t = 0; tmp.clear(); } void dec(int r, int p = -1){ dfs(r, -1); r = find_center(r, -1, cnt[r]); par[r] = p; dfs2(r, -1, r, 0, r); seg[r] = Segment(tmp); reset(r); for(auto[c, d]: adj[r]) if(ban[c]^1) { dec(c, r), mx[r].insert({seg[r].get(st[r][c], en[r][c]), c}); } } set<pp> ans; ll get_ans(){ return prev(end(ans))->ff; } ll get(int r){ if(sz(mx[r]) < 1) return 0; if(sz(mx[r]) == 1) return begin(mx[r])->ff; return prev(end(mx[r]))->ff + prev(prev(end(mx[r])))->ff; } void upd(int u, int v, ll delta){ auto lis = [&](int u){ vector<int> res; while(u + 1) res.pb(u), u = par[u]; return res; }; vector<int> lsu = lis(u), lsv = lis(v); reverse(all(lsu)), reverse(all(lsv)); vector<int> cand; rep(i,0,min(sz(lsu), sz(lsv))){ if(lsu[i] - lsv[i]) break; cand.pb(lsu[i]); } for(int r: cand){ if(st[r][u] > st[r][v]) swap(u, v); int ref = id[r][v]; ans.erase(pp(get(r), r)); mx[r].erase(pp(seg[r].get(st[r][ref], en[r][ref]), ref)); seg[r].upd(st[r][v], en[r][v], delta); mx[r].insert({seg[r].get(st[r][ref], en[r][ref]), ref}); ans.insert(pp(get(r), r)); } } int h[maxn]; int dep(int r){ if(par[r] == -1) return 1; if(h[r] + 1) return h[r]; return h[r] = dep(par[r]) + 1; } pp edge[maxn]; ll vl[maxn]; int main(){ IOS(); int n, q; cin >> n >> q; ll W; cin >> W; rep(i,0,n-1){ int u, v; cin >> u >> v; u--, v--; ll w; cin >> w; adj[u].pb({v, w}), adj[v].pb({u, w}); edge[i] = {u, v}, vl[i] = w; } dec(0); rep(i,0,n) ans.insert({get(i), i}); fill(h, h + maxn, -1); rep(i,0,n) assert(dep(i) < lg); ll lst = 0; while(q--){ ll d, e; cin >> d >> e; d = (d + lst)%(n-1), e = (e + lst)%W; upd(edge[d].ff, edge[d].ss, e - vl[d]); vl[d] = e; cout << (lst = get_ans()) << '\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...