제출 #609291

#제출 시각아이디문제언어결과실행 시간메모리
609291MohammadAghilDynamic Diameter (CEOI19_diameter)C++17
31 / 100
5063 ms390808 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, ll> 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]; struct CHSegment{ vector<ll> seg; int n; CHSegment(){} CHSegment(int n): n(n){ seg.assign(n<<1, 0); } void upd(int i, ll k){ for(i += n, seg[i] = k; i > 1; i >>= 1) seg[i>>1] = max(seg[i], seg[i^1]); } ll get(int l, int r){ ll res = 0; for(l += n, r += n; l < r; l >>= 1, r >>= 1){ if(l&1) res = max(res, seg[l++]); if(r&1) res = max(res, seg[--r]); } return res; } }; struct CHSegment2{ vector<pp> seg; int n; pp comb(pp a, pp b){ if(a.ff < b.ff) swap(a, b); return {a.ff, max(a.ss, b.ff)}; } CHSegment2(){} CHSegment2(int n): n(n){ seg.assign(n<<1, {0, 0}); } void upd(int i, ll k){ for(i += n, seg[i] = {k, 0}; i > 1; i >>= 1) seg[i>>1] = comb(seg[i], seg[i^1]); } pp get(int l, int r){ pp res = {0, 0}; for(l += n, r += n; l < r; l >>= 1, r >>= 1){ if(l&1) res = comb(res, seg[l++]); if(r&1) res = comb(res, seg[--r]); } return res; } }; 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]; CHSegment2 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; ll Dist[maxn]; void dfs2(int r, int p, int cen, ll dist, int ref){ if(p == cen) ref = r; Dist[r] = 0; 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), Dist[r] = max(Dist[r], Dist[c] + d); 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); mx[r] = CHSegment2(t); reset(r); for(auto[c, d]: adj[r]) if(ban[c]^1) { mx[r].upd(st[r][c], Dist[c] + d); dec(c, r); } } CHSegment ans; ll get_ans(){ return ans.seg[1]; } ll get(int r){ return mx[r].seg[1].ff + mx[r].seg[1].ss; } 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]; seg[r].upd(st[r][v], en[r][v], delta); mx[r].upd(st[r][ref], seg[r].get(st[r][ref], en[r][ref])); ans.upd(r, get(r)); } } 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; } ans = CHSegment(n); dec(0); rep(i,0,n) ans.upd(i, get(i)); 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...