제출 #620251

#제출 시각아이디문제언어결과실행 시간메모리
620251ZaniteDynamic Diameter (CEOI19_diameter)C++17
100 / 100
377 ms62416 KiB
#include <bits/stdc++.h>
using namespace std;

using ll	= long long;
using pll	= pair<ll, ll>;
using Edge	= pair<ll, pll>;

#define fi	first
#define se	second

const int maxN	= 1e5 + 5;

const ll INF	= 1e18;

ll n, q, w;
vector<pll> adj[maxN];
vector<Edge> edges;

ll timer;
ll dist[maxN], tin[maxN], tout[maxN];
vector<ll> Euler(1);

void dfs(ll cur, ll par, ll cdist) {
	dist[cur] = cdist;
	Euler.push_back(cur);
	tin[cur] = (ll)Euler.size() - 1;

	for (auto &[nxt, w] : adj[cur]) {
		if (nxt == par) continue;
		dfs(nxt, cur, cdist+w);

		Euler.push_back(cur);
	}

	tout[cur] = (ll)Euler.size() - 1;
}

struct Segtree {
	struct Node {
		ll A, B, AB, BA, ABA, lazy;

		Node() {}

		Node(ll val) {
			A = val;
			B = -2ll * val;
			AB = BA = ABA = -INF;
			lazy = 0;
		}
	};

	ll sz;
	vector<Node> seg;

	Segtree(ll sz) : sz(sz) {
		seg.assign((sz << 2) + 1, Node());
	}

	void updateNode(ll pos, ll val) {
		Node &C = seg[pos];

		C.A += val;
		C.B -= 2ll * val;
		C.AB -= val;
		C.BA -= val;
		C.lazy += val;
	}

	void checkLazy(ll pos) {
		if (seg[pos].lazy != 0) {
			ll lc = pos << 1, rc = lc | 1;
			updateNode(lc, seg[pos].lazy);
			updateNode(rc, seg[pos].lazy);
			seg[pos].lazy = 0;
		}
	}

	Node merge(Node L, Node R) {
		Node N = Node(0);

		N.A = max(L.A, R.A);
		N.B = max(L.B, R.B);

		N.AB = max({
			L.AB,
			R.AB,
			L.A + R.B
		});

		N.BA = max({
			L.BA,
			R.BA,
			L.B + R.A
		});

		N.ABA = max({
			L.ABA,
			R.ABA,
			L.A + R.BA,
			L.AB + R.A
		});

		return N;
	}

	void build(ll pos, ll l, ll r) {
		if (l == r) {
			seg[pos] = Node(dist[Euler[l]]);
			return;
		}

		ll m = (l+r) >> 1, lc = pos << 1, rc = lc | 1;
		build(lc, l, m);
		build(rc, m+1, r);
		seg[pos] = merge(seg[lc], seg[rc]);
	}
	void build() {build(1, 1, sz);}

	void update(ll pos, ll l, ll r, ll ul, ll ur, ll val) {
		if (l > r || ul > ur || l > ur || ul > r) return;
		if (ul <= l && r <= ur) {
			updateNode(pos, val);
			return;
		}

		checkLazy(pos);

		ll m = (l+r) >> 1, lc = pos << 1, rc = lc | 1;
		update(lc, l, m, ul, ur, val);
		update(rc, m+1, r, ul, ur, val);
		seg[pos] = merge(seg[lc], seg[rc]);
	}
	void update(ll ul, ll ur, ll val) {update(1, 1, sz, ul, ur, val);}

	ll query() {
		return max({seg[1].ABA, seg[1].AB, seg[1].BA});
	}
};

int main() {
	scanf("%lld %lld %lld", &n, &q, &w);
	for (ll a, b, c, i = 1; i < n; i++) {
		scanf("%lld %lld %lld", &a, &b, &c);
		adj[a].push_back({b, c});
		adj[b].push_back({a, c});

		edges.push_back({c, {a, b}});
	}
	dfs(1, 0, 0);

	ll ES = (ll)Euler.size() - 1;

	Segtree S(ES);
	S.build();
	for (auto &[cw, p] : edges) {
		if (tin[p.se] < tin[p.fi]) {swap(p.fi, p.se);}
	}

	ll last = 0;
	for (ll d, e, i = 1; i <= q; i++) {
		scanf("%lld %lld", &d, &e);
		d = (d + last) % (n - 1);
		e = (e + last) % w;

		auto &[cw, p] = edges[d];

		S.update(tin[p.se], tout[p.se], e - cw);
		cw = e;

		last = S.query();
		printf("%lld\n", last);
	}
}

컴파일 시 표준 에러 (stderr) 메시지

diameter.cpp: In function 'int main()':
diameter.cpp:141:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  141 |  scanf("%lld %lld %lld", &n, &q, &w);
      |  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diameter.cpp:143:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  143 |   scanf("%lld %lld %lld", &a, &b, &c);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diameter.cpp:161:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  161 |   scanf("%lld %lld", &d, &e);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~
#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...