Submission #201699

#TimeUsernameProblemLanguageResultExecution timeMemory
201699MiricaMateiDynamic Diameter (CEOI19_diameter)C++14
31 / 100
5084 ms255676 KiB
#include <bits/stdc++.h> using namespace std; const int MAXN = 100005; struct Node { long long maxim; long long lazy; Node() { maxim = lazy = 0; } }; class SegTree { public: int n; Node* aint; void init(int _n, vector<long long>v) { n = _n; aint = new Node[4 * n + 5]; for (int i = 0; i < v.size(); ++i) update(1, 1, n, i + 1, v[i]); } void update(int node, int l, int r, int pos, long long val) { if (l == r) { aint[node].maxim = val; aint[node].lazy = 0; return ; } int m = (l + r) / 2; if (pos <= m) update(2 * node, l, m, pos, val); else update(2 * node + 1, m + 1, r, pos, val); aint[node] = join(aint[2 * node], aint[2 * node + 1]); } void updateL(int node, int l, int r, int x, int y, long long val) { if (x <= l && r <= y) { aint[node].lazy += val; propag(node, r - l + 1); return ; } propag(node, r - l + 1); if (r < x) return ; if (l > y) return ; int m = (r + l) / 2; updateL(2 * node, l, m, x, y, val); updateL(2 * node + 1, m + 1, r, x, y, val); aint[node] = join(aint[2 * node], aint[2 * node + 1]); } long long query() { propag(1, n); return aint[1].maxim; } Node join(Node a, Node b) { Node aux; aux.maxim = max(a.maxim, b.maxim); aux.lazy = 0; return aux; } void propag(int node, int len) { aint[node].maxim += aint[node].lazy; if (len > 1) { aint[2 * node].lazy += aint[node].lazy; aint[2 * node + 1].lazy += aint[node].lazy; } aint[node].lazy = 0; } void updL(pair<int, int>aux, long long val) { updateL(1, 1, n, aux.first, aux.second, val); } }; class Comp { public: vector<SegTree>v1; vector<vector< pair<int, int> > >v2; multiset<long long>s1; } cp[MAXN]; multiset<long long>ans1; map<pair<int, int>, int>mp; map<pair<int, int>, pair<int, int> >posComp; vector<int>wComp[MAXN]; set<pair<int, long long> >G[MAXN]; long long cost[MAXN]; int tsz; int sz[MAXN]; void getSize(int v, int f) { sz[v] = 1; for (auto it:G[v]) if (it.first != f) { getSize(it.first, v); sz[v] += sz[it.first]; } } int getc(int node, int f) { for (auto it:G[node]) if (it.first != f && tsz / 2 < sz[it.first]) return getc(it.first, node); return node; } int k, ind, ind1 = 0; long long dist[MAXN]; int lin[MAXN], first[MAXN], last[MAXN]; pair<int, pair<int, int> >mc[MAXN]; void dfs1(int node, int f) { lin[++ind] = node; first[node] = ind; for (auto it:G[node]) if (it.first != f) { ind1++; int auxind = ind1; mc[ind1].first = mp[{it.first, node}]; mc[ind1].second.first = ind + 1; dist[it.first] = dist[node] + it.second; dfs1(it.first, node); mc[auxind].second.second = ind; } last[node] = ind; } void dfs(int node) { getSize(node, 0); tsz = sz[node]; int c = getc(node, 0); ++k; int j = 0; for (auto it:G[c]) { j++; ind = 0; ind1 = 1; dist[it.first] = it.second; dfs1(it.first, c); vector<long long>aux; for (int i = 1; i <= ind; ++i) aux.push_back(dist[lin[i]]); SegTree aux1; aux1.init(ind, aux); cp[k].v1.push_back(aux1); cp[k].s1.insert(aux1.query()); vector<pair<int, int> >aux2; int cmm = mp[{it.first, c}]; posComp[{k, cmm}] = {j, 1}; aux2.push_back({1, ind}); wComp[cmm].push_back(k); for (int i = 2; i <= ind1; ++i) { posComp[{k, mc[i].first}] = {j, i}; aux2.push_back(mc[i].second); wComp[mc[i].first].push_back(k); } cp[k].v2.push_back(aux2); G[it.first].erase({c, it.second}); } if (!cp[k].s1.empty()) { long long ans = 0; multiset<long long>::iterator it1 = cp[k].s1.end(); it1--; ans += (*it1); if (it1 != cp[k].s1.begin()) { it1--; ans += (*it1); } ans1.insert(ans); } for (auto it:G[c]) dfs(it.first); } void upd(int ed, long long nc) { for (auto it:wComp[ed]) { pair<int, int>aux = posComp[{it, ed}]; long long ans = 0; multiset<long long>::iterator it1 = cp[it].s1.end(); it1--; ans += (*it1); if (it1 != cp[it].s1.begin()) { it1--; ans += (*it1); } ans1.erase(ans1.find(ans)); cp[it].s1.erase(cp[it].s1.find(cp[it].v1[aux.first - 1].query())); cp[it].v1[aux.first - 1].updL(cp[it].v2[aux.first - 1][aux.second - 1], nc - cost[ed]); cp[it].s1.insert(cp[it].v1[aux.first - 1].query()); ans = 0; it1 = cp[it].s1.end(); it1--; ans += (*it1); if (it1 != cp[it].s1.begin()) { it1--; ans += (*it1); } ans1.insert(ans); } cost[ed] = nc; } long long qry() { multiset<long long>::iterator it = ans1.end(); it--; return (*it); } int main() { ios::sync_with_stdio(0); cin.tie(); //freopen("date.in", "r", stdin); //freopen("date.out", "w", stdout); int n, q; long long w; cin >> n >> q >> w; for (int i = 1; i < n; ++i) { int x, y; long long z; cin >> x >> y >> z; mp[{x, y}] = mp[{y, x}] = i; G[x].insert({y, z}); G[y].insert({x, z}); cost[i] = z; } dfs(1); long long last = 0; for (int i = 1; i <= q; ++i) { int d; long long e; cin >> d >> e; d = (d + last) % (n - 1) + 1; e = (e + last) % w; upd(d, e); last = qry(); cout << last << '\n'; } return 0; }

Compilation message (stderr)

diameter.cpp: In member function 'void SegTree::init(int, std::vector<long long int>)':
diameter.cpp:24:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 0; i < v.size(); ++i)
                     ~~^~~~~~~~~~
#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...