Submission #1299937

#TimeUsernameProblemLanguageResultExecution timeMemory
1299937KickingKunDynamic Diameter (CEOI19_diameter)C++20
100 / 100
230 ms55524 KiB
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define ull unsigned long long
#define ld long double
#define bigint __int128
#define emb emplace_back
#define pb push_back
#define pii pair <int, int>
#define fi first
#define se second
#define all(v) v.begin(), v.end()
#define Task ""

#define MASK(k) (1ull << k)
#define bitcnt(k) __builtin_popcount(k)
#define testBit(n, k) ((n >> k) & 1)
#define flipBit(n, k) (n ^ (1ll << k))
#define offBit(n, k) (n & ~MASK(k))
#define onBit(n, k) (n | (1ll << k))

template <class T> bool minimize(T &a, T b) {if (a > b) {a = b; return true;} return false;}
template <class T> bool maximize(T &a, T b) {if (a < b) {a = b; return true;} return false;}

const int N = 1e5 + 5, lim = 60, mod = 1e9 + 7;
const ll INF = 1e18;

struct SegmentTree { // max dist[u] - 2 * dist[p] + dist[v]
	struct Node {
		ll A, B, AB, BC, total;
		Node () {
			A = B = total = -INF;
			AB = BC = -INF;
		}
		Node (ll x) {
			A = x; B = -2 * x;
			AB = BC = -x;
			total = 0;
		}

		void increase(ll val) {
			A += val; B -= 2 * val;
			AB -= val; BC -= val;
		}

		Node operator + (const Node &other) {
			Node res;
			res.A = max(A, other.A);
			res.B = max(B, other.B);
			res.AB = max({AB, other.AB, A + other.B});
			res.BC = max({BC, other.BC, B + other.A});
			res.total = max({total, other.total, A + other.BC, AB + other.A});
			return res;
		}
	};

	vector <Node> st;
	vector <ll> lazy;

	SegmentTree (int n) {
		st.assign(n * 4 + 5, Node(0));
		lazy.assign(n * 4 + 5, 0);
	}

	void push_down(int id) {
		ll k = lazy[id]; lazy[id] = 0;
		st[id << 1].increase(k); lazy[id << 1] += k;
		st[id << 1 | 1].increase(k); lazy[id << 1 | 1] += k;
	}

	void update(int id, int l, int r, int u, int v, ll val) {
		if (u > r || v < l) return;
		if (u <= l && r <= v) {
			st[id].increase(val);
			lazy[id] += val;
			return;
		}

		int mid = (l + r) >> 1; push_down(id);
		update(id << 1, l, mid, u, v, val);
		update(id << 1 | 1, mid + 1, r, u, v, val);
		st[id] = st[id << 1] + st[id << 1 | 1];
	}

	ll get() {
		return st[1].total;
	}
};

struct Edge {
	int u, v; ll w;
	Edge () {}
	Edge (int a, int b, ll c) {
		u = a; v = b; w = c;
	}
} edge[N];

int n, q; ll W, dist[N];
vector <int> adj[N];
int childEdge[N];

int tin[N], tout[N], tour[N << 1], dfsTimes = 0;

void dfs(int u, int p = -1) {
	tin[u] = tout[u] = ++dfsTimes; tour[dfsTimes] = u;
	for (int i: adj[u]) {
		int v = edge[i].u ^ edge[i].v ^ u;
		if (v != p) {
			childEdge[i] = v; dist[v] = dist[u] + edge[i].w;
			dfs(v, u);
			tout[u] = ++dfsTimes; tour[dfsTimes] = u;
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

	if (fopen(Task".inp", "r")) {
		freopen(Task".inp", "r", stdin);
		freopen(Task".out", "w", stdout);
	}

	cin >> n >> q >> W;
	for (int i = 0; i < n - 1; i++) {
		int u, v; ll w; cin >> u >> v >> w;
		edge[i] = Edge(u, v, w);
		adj[u].emplace_back(i);
		adj[v].emplace_back(i);
	}

	dfs(1);

	SegmentTree ST(dfsTimes);
	for (int i = 1; i <= dfsTimes; i++) {
		ST.update(1, 1, dfsTimes, i, i, dist[tour[i]]);
	}

	ll ans = 0;
	while (q--) {
		ll d, e; cin >> d >> e;
		d = (d + ans) % (n - 1);
		e = (e + ans) % W;

		int v = childEdge[d];
		ST.update(1, 1, dfsTimes, tin[v], tout[v], -edge[d].w + e);
		edge[d].w = e;

		ans = ST.get(); 
		cout << ans << '\n';
	}
}

Compilation message (stderr)

diameter.cpp: In function 'int main()':
diameter.cpp:121:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  121 |                 freopen(Task".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
diameter.cpp:122:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  122 |                 freopen(Task".out", "w", stdout);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#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...