#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
using ll = long long;
using ii = pair<int, int>;
using pll = pair<ll, ll>;
struct SegmentSegmentTree {
int lv;
vector<pll> d;
vector<ll> ins;
//1..n
SegmentSegmentTree(int n) {
lv = 2;
while(lv < n + 2)
lv *= 2;
d.resize(2 * lv + 3, {-1e18, 0});
ins.resize(2 * lv + 3);
for(int i = 1 ; i <= lv ; i++)
d[lv + i - 1].Y = i;
}
void initv(int i, ll x) {
d[lv + i - 1].X = x;
}
void process_init() {
for(int i = lv - 1 ; i >= 1 ; i--)
d[i] = max(d[2 * i], d[2 * i + 1]);
}
void insert(int a, int b, int l, int r, int w, ll x) {
if(a > r || b < l || l > r)
return ;
if(a <= l && r <= b) {
ins[w] += x;
d[w].X += x;
return;
}
insert(a, b, l, (l + r) / 2, 2 * w, x);
insert(a, b, (l + r) / 2 + 1, r, 2 * w + 1, x);
d[w] = max(d[2 * w], d[2 * w + 1]);
d[w].X += ins[w];
}
void insert(int a, int b, ll x) {
insert(a, b, 1, lv, 1, x);
}
pll query(int a, int b, int l, int r, int w) {
if(a > r || b < l || l > r)
return {-1e18, 0};
if(a <= l && r <= b)
return d[w];
pll p1 = query(a, b, l, (l + r) / 2, 2 * w);
pll p2 = query(a, b, (l + r) / 2 + 1, r, 2 * w + 1);
p1 = max(p1, p2);
p1.X += ins[w];
return p1;
}
pll query(int a, int b) {
return query(a, b, 1, lv, 1);
}
};
int n, q;
ll w;
vector<pll> G[100007];
ii E[100007];
ll ecost[100007];
int p[100007], sz[100007];
int in[100007], out[100007];
int rein[100007];
int nxt_num = 1;
int first[100007];
SegmentSegmentTree paths(100007);
SegmentSegmentTree subtrees(100007);
void dfs(int w) {
sz[w] = 1;
for(auto u : G[w]) {
if(u.X != p[w]) {
p[u.X] = w;
dfs(u.X);
sz[w] += sz[u.X];
}
}
}
ll dfs2(int w, ll dist) {
for(auto &u : G[w])
if(sz[u.X] > sz[G[w][0].X])
swap(u, G[w][0]);
in[w] = out[w] = nxt_num++;
rein[in[w]] = w;
subtrees.initv(in[w], dist);
ll maxdist = dist;
for(auto u : G[w]) {
if(u == G[w][0])
first[u.X] = first[w];
else
first[u.X] = u.X;
if(u != G[w][0])
maxdist = max(maxdist, dfs2(u.X, dist + u.Y));
else
dfs2(u.X, dist + u.Y);
out[w] = out[u.X];
}
paths.initv(in[w], maxdist - 2LL * dist);
return maxdist;
}
ll longest_path() {
auto q = subtrees.query(1, n);
int w = rein[q.Y], pre = 0;
ll dw = q.X;
//~ cout << dw << " " << w << endl;
ll res = 0;
while(w) {
if(!pre || first[pre] == first[w]) {
res = max(res, paths.query(in[first[w]], in[w]).X + dw);
//~ cout << in[first[w]] << " " << in[w] << " " << w << " " << res << " " << paths.query(in[first[w]], in[w]).Y << endl;
pre = first[w];
w = p[first[w]];
} else {
ll pdist = subtrees.query(in[w], in[w]).X;
res = max(res, subtrees.query(in[w], in[pre] - 1).X + dw - 2LL * pdist);
//~ cout << w << " " << pre << " " << pdist << " " << dw << " " << res << endl;
res = max(res, subtrees.query(out[pre] + 1, out[w]).X + dw - 2LL * pdist);
//~ cout << w << " " << pre << " " << pdist << " " << dw << " " << res << endl;
pre = w;
w = p[w];
}
}
return res;
}
void change_edge(int e, ll x) {
//~ cout << e << " " << x << endl;
int w = E[e].X;
int u = E[e].Y;
if(in[w] > in[u])
swap(w, u);
ll delta = x - ecost[e];
ecost[e] = x;
paths.insert(in[u], out[u], -delta);
subtrees.insert(in[u], out[u], delta);
w = p[first[u]];
//~ cout << w << " " << u << endl;
while(w) {
//~ cout << w << endl;
ll actv = paths.query(in[w], in[w]).X;
ll pdist = subtrees.query(in[w], in[w]).X;
ll newv = subtrees.query(out[G[w][0].X] + 1, out[w]).X - 2LL * pdist;
//~ cout << actv << " " << newv << endl;
paths.insert(in[w], in[w], newv - actv);
w = p[first[w]];
}
}
int main() {
scanf("%d%d%lld", &n, &q, &w);
for(int i = 1 ; i < n ; i++) {
int a, b;
ll c;
scanf("%d%d%lld", &a, &b, &c);
G[a].emplace_back(b, c);
G[b].emplace_back(a, c);
ecost[i] = c;
E[i] = {a, b};
}
dfs(1);
for(int i = 1 ; i <= n ; i++) {
for(int j = 0 ; j < G[i].size() ; j++) {
if(G[i][j].X == p[i]) {
G[i].erase(G[i].begin() + j);
break;
}
}
}
first[1] = 1;
dfs2(1, 0);
subtrees.process_init();
paths.process_init();
//~ for(int i = 1 ; i <= n ; i++)
//~ cout << i << " "<< first[i] << endl;
//~ cout << longest_path() << endl;
ll last = 0;
while(q--) {
ll d, e;
scanf("%lld%lld", &d, &e);
d = (d + last) % (n - 1);
e = (e + last) % w;
change_edge(d + 1, e);
//~ for(int i = 1 ; i <= n ; i++)
//~ cout << i << " " << in[i] << " " << paths.query(in[i], in[i]).X << " " << paths.query(in[i], in[i]).Y << endl;
printf("%lld\n", last = longest_path());
}
return 0;
}
Compilation message
diameter.cpp: In function 'int main()':
diameter.cpp:200:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for(int j = 0 ; j < G[i].size() ; j++) {
~~^~~~~~~~~~~~~
diameter.cpp:187:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d%lld", &n, &q, &w);
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
diameter.cpp:191:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d%lld", &a, &b, &c);
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
diameter.cpp:221:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%lld%lld", &d, &e);
~~~~~^~~~~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
9 ms |
14976 KB |
Output is correct |
2 |
Incorrect |
9 ms |
14976 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
9 ms |
14976 KB |
Output is correct |
2 |
Incorrect |
9 ms |
14976 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
14976 KB |
Output is correct |
2 |
Correct |
9 ms |
14976 KB |
Output is correct |
3 |
Correct |
22 ms |
15104 KB |
Output is correct |
4 |
Correct |
68 ms |
15224 KB |
Output is correct |
5 |
Correct |
288 ms |
16248 KB |
Output is correct |
6 |
Correct |
9 ms |
14976 KB |
Output is correct |
7 |
Correct |
12 ms |
15104 KB |
Output is correct |
8 |
Correct |
10 ms |
15104 KB |
Output is correct |
9 |
Correct |
15 ms |
15104 KB |
Output is correct |
10 |
Correct |
74 ms |
15360 KB |
Output is correct |
11 |
Correct |
322 ms |
16376 KB |
Output is correct |
12 |
Correct |
12 ms |
15488 KB |
Output is correct |
13 |
Correct |
12 ms |
15616 KB |
Output is correct |
14 |
Correct |
18 ms |
15616 KB |
Output is correct |
15 |
Correct |
78 ms |
15864 KB |
Output is correct |
16 |
Correct |
335 ms |
17016 KB |
Output is correct |
17 |
Correct |
55 ms |
24808 KB |
Output is correct |
18 |
Correct |
56 ms |
24780 KB |
Output is correct |
19 |
Correct |
63 ms |
24940 KB |
Output is correct |
20 |
Correct |
131 ms |
25192 KB |
Output is correct |
21 |
Correct |
428 ms |
26472 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
17 ms |
15104 KB |
Output is correct |
2 |
Correct |
80 ms |
15300 KB |
Output is correct |
3 |
Correct |
370 ms |
15864 KB |
Output is correct |
4 |
Correct |
713 ms |
16744 KB |
Output is correct |
5 |
Correct |
24 ms |
16128 KB |
Output is correct |
6 |
Correct |
113 ms |
16256 KB |
Output is correct |
7 |
Incorrect |
659 ms |
16888 KB |
Output isn't correct |
8 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1124 ms |
29816 KB |
Output is correct |
2 |
Correct |
1288 ms |
29940 KB |
Output is correct |
3 |
Correct |
1150 ms |
29816 KB |
Output is correct |
4 |
Correct |
1189 ms |
29816 KB |
Output is correct |
5 |
Correct |
1133 ms |
30036 KB |
Output is correct |
6 |
Correct |
997 ms |
29804 KB |
Output is correct |
7 |
Correct |
681 ms |
32944 KB |
Output is correct |
8 |
Correct |
745 ms |
32932 KB |
Output is correct |
9 |
Correct |
556 ms |
32888 KB |
Output is correct |
10 |
Correct |
682 ms |
32888 KB |
Output is correct |
11 |
Correct |
679 ms |
32596 KB |
Output is correct |
12 |
Correct |
456 ms |
31596 KB |
Output is correct |
13 |
Correct |
364 ms |
37496 KB |
Output is correct |
14 |
Correct |
348 ms |
37496 KB |
Output is correct |
15 |
Correct |
335 ms |
37496 KB |
Output is correct |
16 |
Correct |
361 ms |
37496 KB |
Output is correct |
17 |
Correct |
357 ms |
36980 KB |
Output is correct |
18 |
Correct |
330 ms |
33424 KB |
Output is correct |
19 |
Correct |
333 ms |
37496 KB |
Output is correct |
20 |
Correct |
347 ms |
37496 KB |
Output is correct |
21 |
Correct |
342 ms |
37624 KB |
Output is correct |
22 |
Correct |
351 ms |
37496 KB |
Output is correct |
23 |
Correct |
348 ms |
36980 KB |
Output is correct |
24 |
Correct |
319 ms |
33388 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
9 ms |
14976 KB |
Output is correct |
2 |
Incorrect |
9 ms |
14976 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |