이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define ar array
using namespace std;
using ll = long long;
const int mxN = 1e5;
vector<ar<ll, 2>> g[mxN];
int frst[mxN], last[mxN];
ll depth[mxN];
vector<int> order;
void dfs(int cur, int prv, ll d) {
frst[cur] = (int)order.size();
last[cur] = (int)order.size();
depth[cur] = d;
order.push_back(cur);
for (auto [nxt, w] : g[cur]) {
if (nxt == prv) continue;
dfs((int)nxt, cur, d+w);
last[cur] = (int)order.size();
order.push_back(cur);
}
}
const ll INF = 1LL<<60;
struct S {
ll lmin, lmax, mmin, rmax, rmin, longest;
S() : lmin(INF), lmax(INF), mmin(INF), rmax(INF), rmin(INF), longest(INF) {}
S(ll d) : lmin(d), lmax(d), mmin(d), rmax(d), rmin(d), longest(0) {}
S(ll lm, ll l, ll m, ll r, ll rm) :
lmin(lm), lmax(l), mmin(m), rmax(r), rmin(rm), longest(l + r - 2*m) {}
bool operator<(const S &o) const {
return longest < o.longest;
}
void pull(S l, S r) {
if (l.lmin == INF) return void(*this = r);
if (r.lmin == INF) return void(*this = l);
vector<ll> v {
l.lmin, l.lmax, l.mmin, l.rmax, l.rmin,
r.lmin, r.lmax, r.mmin, r.rmax, r.rmin,
};
vector<S> alts;
for (int i = 1; i < 9; ++i) {
for (int j = i+1; j < 9; ++j) {
ll premin = INF;
for (int k = 0; k <= i; ++k) premin = min(premin, v[k]);
ll midmin = INF;
for (int k = i; k <= j; ++k) midmin = min(midmin, v[k]);
ll sufmin = INF;
for (int k = j; k < 10; ++k) sufmin = min(sufmin, v[k]);
alts.emplace_back(premin, v[i], midmin, v[j], sufmin);
}
}
*this = *max_element(alts.begin(), alts.end());
}
};
struct F {
ll s = 0;
void apply(F &f) {
f.s += s;
}
void apply(S &v) {
v.lmin += s;
v.lmax += s;
v.mmin += s;
v.rmax += s;
v.rmin += s;
}
};
const int mxL = mxN + mxN-1;
const int offset = 2<<__lg(mxL-1);
S values[2*offset];
F lazy[offset];
int push(int I, int l, int r) {
lazy[I].apply(values[2*I]);
lazy[I].apply(values[2*I+1]);
if (2*I < offset) {
lazy[I].apply(lazy[2*I]);
lazy[I].apply(lazy[2*I+1]);
}
lazy[I] = F();
return l + (r-l+1)/2;
}
S qry(int i, int j, int I = 1, int l = 0, int r = offset-1) {
assert(!(i > r || j < l));
if (i <= l && j >= r) return values[I];
int mid = push(I, l, r);
S res;
res.pull(
(i<mid?qry(i, j, 2*I, l, mid-1):S()),
(j>=mid?qry(i, j, 2*I+1, mid, r):S())
);
return res;
}
void upd(int i, int j, F f, int I = 1, int l = 0, int r = offset-1) {
assert(!(i > r || j < l));
if (i <= l && j >= r) {
f.apply(values[I]);
if (I < offset) f.apply(lazy[I]);
return;
}
int mid = push(I, l, r);
if (i < mid) upd(i, j, f, 2*I, l, mid-1);
if (j >= mid) upd(i, j, f, 2*I+1, mid, r);
values[I].pull(values[2*I], values[2*I+1]);
}
int main() {
cin.tie(0)->sync_with_stdio(0);
int n, q; ll mxw; cin >> n >> q >> mxw;
vector<ar<ll, 3>> e(n-1);
for (auto &[i, j, w] : e) {
cin >> i >> j >> w; --i, --j;
g[i].push_back({j, w});
g[j].push_back({i, w});
}
dfs(0, -1, 0);
assert((int)order.size() == 2*n-1);
assert(offset >= order.size());
for (int i = 0; i < (int)order.size(); ++i)
values[offset+i] = S(depth[order[i]]);
for (int i = offset-1; i > 0; --i)
values[i].pull(values[2*i], values[2*i+1]);
ll ans = 0;
for (int qq = 0; qq < q; ++qq) {
int ei; ll w; cin >> ei >> w;
ei = int((ei+ans)%(n-1));
w = (w+ans)%mxw;
auto &[i, j, pw] = e[ei];
if (depth[i] > depth[j]) swap(i, j);
ll change = w-pw;
pw = w;
upd(frst[j], last[j], {change});
ans = qry(0, offset-1).longest;
cout << ans << '\n';
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |