Submission #240012

#TimeUsernameProblemLanguageResultExecution timeMemory
240012karmaDynamic Diameter (CEOI19_diameter)C++14
100 / 100
4552 ms155396 KiB
#include <bits/stdc++.h> #define pb emplace_back #define ll long long #define fi first #define se second #define mp make_pair //#define int int64_t using namespace std; const int N = (int)1e5 + 2; const ll inf = 1ll << 60; typedef pair<int, int> pii; int lg[N]; struct TTree { /// get max value in range, add x in a range vector<pair<ll, int>> st; vector<ll> lz; vector<pii> range; int n, h; ll val; pair<ll, int> top; void init(int _n) { n = _n; h = sizeof(int) * 8 - __builtin_clz(n); st.resize(2 * n + 2, mp(0, 0)); lz.resize(2 * n + 2, 0); for(int i = n - 1; i >= 0; --i) st[i + n].se = i; } void apply(int x, ll val) { st[x].fi += val; if(x < n) lz[x] += val; } inline pair<ll, int> Max(const pair<ll, int>& x, const pair<ll, int>& y) { if(x.fi < y.fi) return y; return x; } void build(int x) { while(x > 1) { x >>= 1; st[x] = Max(st[x << 1], st[x << 1 | 1]); st[x].fi += lz[x]; } } void push(int x) { for(int i, s = h; s > 0; --s) { i = x >> s; if(lz[i] != 0) { apply(x << 1, lz[i]); apply(x << 1 | 1, lz[i]); lz[i] = 0; } } } void upd(int l, int r, ll val) { l += n, r += (n + 1); int l0 = l, r0 = r; for(; l < r; l >>= 1, r >>= 1) { if(l & 1) apply(l ++, val); if(r & 1) apply(-- r, val); } build(l0); build(r0 - 1); } ll diameter() { top = st[1]; val = st[1].fi; upd(range[top.se].fi, range[top.se].se, -top.fi); val += max(st[1].fi, 0ll); upd(range[top.se].fi, range[top.se].se, top.fi); return val; } }; vector<TTree> it; struct TEdge { int u, v; ll w; vector<int> it; vector<pii> range; } e[N]; vector<pii> adj[N]; ll W, dis[N]; int n, q, Time, head[N], in[N], out[N], sz[N], big[N]; bool del[N]; int find(int u) { function<void(int, int)> dfs = [&](int u, int p) { sz[u] = 1, big[u] = 0; for(auto v: adj[u]) { if(v.fi == p || del[v.fi]) continue; dfs(v.fi, u); sz[u] += sz[v.fi]; if(sz[v.fi] > sz[big[u]]) big[u] = v.fi; } }; dfs(u, -1); int cen = u; while(sz[big[cen]] * 2 >= sz[u] && big[cen]) cen = big[cen]; return cen; } multiset<ll, greater<ll>> ans; void centroid(int u) { int root = find(u); it.push_back({}); function<void(int, int)> dfs = [&](int u, int p) { in[u] = ++Time; if(p == root) head[u] = u; else if(p != -1) head[u] = head[p]; for(auto v: adj[u]) { if(del[v.fi] || v.fi == p) continue; dis[v.fi] = dis[u] + e[v.se].w; it.back().range.pb(v.se, v.fi); dfs(v.fi, u); } out[u] = Time; }; Time = -2, dis[root] = 0; dfs(root, -1); del[root] = 1; if((int)it.back().range.size()) { it.back().init((int)it.back().range.size()); for(auto& p: it.back().range) { e[p.fi].it.pb((int)it.size() - 1); e[p.fi].range.pb(in[p.se], out[p.se]); it.back().upd(in[p.se], in[p.se], dis[p.se]); p.fi = in[head[p.se]], p.se = out[head[p.se]]; } ans.insert(it.back().diameter()); } for(auto v: adj[root]) { if(del[v.fi]) continue; centroid(v.fi); } } ///40071305542068 int32_t main() { ios_base::sync_with_stdio(0); cin.tie(0), cout.tie(0); #define Task "test" if(fopen(Task".inp", "r")) { freopen(Task".inp", "r", stdin); freopen(Task".out", "w", stdout); } cin >> n >> q >> W; for(int i = 1; i <= n; ++i) lg[i] = log2(i) + 1; for(int i = 0; i < n - 1; ++i) { cin >> e[i].u >> e[i].v >> e[i].w; adj[e[i].u].pb(e[i].v, i); adj[e[i].v].pb(e[i].u, i); } centroid(1); ll w, lst = 0; for(int id, tree; q > 0; --q) { cin >> id >> w; id = ((ll)id + lst) % (n - 1); w = (w + lst) % W; for(int i = 0; i < e[id].it.size(); ++i) { tree = e[id].it[i]; ans.erase(ans.find(it[tree].diameter())); it[tree].upd((int)e[id].range[i].fi, (int)e[id].range[i].se, w - e[id].w); ans.insert(it[tree].diameter()); } e[id].w = w; cout << (lst = *ans.begin()) << '\n'; } }

Compilation message (stderr)

diameter.cpp: In function 'int32_t main()':
diameter.cpp:154:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int i = 0; i < e[id].it.size(); ++i) {
                        ~~^~~~~~~~~~~~~~~~~
diameter.cpp:139:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
         freopen(Task".inp", "r", stdin);
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
diameter.cpp:140:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
         freopen(Task".out", "w", stdout);
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
diameter.cpp: In function 'void centroid(int)':
diameter.cpp:104:29: warning: array subscript is below array bounds [-Warray-bounds]
         if(p == root) head[u] = u;
                       ~~~~~~^
#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...