結果

問題 No.399 動的な領主
ユーザー pekempeypekempey
提出日時 2016-07-19 15:03:50
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 371 ms / 2,000 ms
コード長 2,459 bytes
コンパイル時間 1,476 ms
コンパイル使用メモリ 168,812 KB
実行使用メモリ 18,944 KB
最終ジャッジ日時 2024-11-07 19:42:28
合計ジャッジ時間 5,380 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 3 ms
5,888 KB
testcase_01 AC 4 ms
5,888 KB
testcase_02 AC 4 ms
5,760 KB
testcase_03 AC 4 ms
5,888 KB
testcase_04 AC 6 ms
6,016 KB
testcase_05 AC 27 ms
6,784 KB
testcase_06 AC 371 ms
14,080 KB
testcase_07 AC 326 ms
14,080 KB
testcase_08 AC 328 ms
14,464 KB
testcase_09 AC 343 ms
14,208 KB
testcase_10 AC 7 ms
5,888 KB
testcase_11 AC 21 ms
6,912 KB
testcase_12 AC 261 ms
14,720 KB
testcase_13 AC 217 ms
14,848 KB
testcase_14 AC 86 ms
18,944 KB
testcase_15 AC 101 ms
18,944 KB
testcase_16 AC 145 ms
15,232 KB
testcase_17 AC 339 ms
14,080 KB
testcase_18 AC 327 ms
14,336 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:118:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  118 |                 scanf("%d %d", &u, &v);
      |                 ~~~~~^~~~~~~~~~~~~~~~~
main.cpp:133:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  133 |                 scanf("%d %d", &u, &v);
      |                 ~~~~~^~~~~~~~~~~~~~~~~

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

vector<int> g[101010];

namespace HL {
	const int N = 1e5 + 10;
	int vid[N];
	int head[N];
	int parent[N];
	int heavy[N];
	int sub[N];

	void dfs(int curr, int prev) {
		parent[curr] = prev;
		sub[curr] = 1;
		pair<int, int> h(-1, -1);
		for (int next : g[curr]) {
			if (next == prev) continue;
			dfs(next, curr);
			sub[curr] += sub[next];
			h = max(h, make_pair(sub[next], next));
		}
		heavy[curr] = h.second;
	}

	void bfs() {
		int k = 0;
		queue<int> q({ 0 });
		while (!q.empty()) {
			int h = q.front(); q.pop();
			for (int i = h; i != -1; i = heavy[i]) {
				vid[i] = k++;
				head[i] = h;
				for (int j : g[i]) {
					if (j == parent[i]) continue;
					if (j == heavy[i]) continue;
					q.push(j);
				}
			}
		}
	}

	void build() {
		dfs(0, -1);
		bfs();
	}

	void for_each(int u, int v, function<void(int, int)> f) {
		if (vid[u] > vid[v]) swap(u, v);
		f(max(vid[head[v]], vid[u]), vid[v]);
		if (head[u] != head[v]) for_each(u, parent[head[v]], f);
	}
}

const int N = 1 << 17;
long long sum[N * 2];
long long lazy[N * 2];

void push(int k, int w) {
	if (lazy[k] == 0) return;
	sum[k] += lazy[k] * w;
	if (w > 1) {
		lazy[k * 2 + 0] += lazy[k];
		lazy[k * 2 + 1] += lazy[k];
	}
	lazy[k] = 0;
}

long long get_val(int k, int w) {
	return sum[k] + lazy[k] * w;
}

void update(int l, int r, long long v) {
	l += N;
	r += N;
	int L = l;
	int R = r;

	for (; l < r; l >>= 1, r >>= 1) {
		if (l & 1) lazy[l++] += v;
		if (r & 1) lazy[--r] += v;
	}

	int w = 1;
	for (; L > 1; L >>= 1, R >>= 1) {
		sum[L >> 1] = get_val(L, w) + get_val(L ^ 1, w);
		sum[R >> 1] = get_val(R, w) + get_val(R ^ 1, w);
		w *= 2;
	}
}

long long query(int l, int r) {
	l += N;
	r += N;

	for (int i = 17; i >= 0; i--) {
		push(l >> i, 1 << i);
		push(r >> i, 1 << i);
	}
	
	long long res = 0;
	int w = 1;
	for (; l < r; l >>= 1, r >>= 1) {
		if (l & 1) res += get_val(l++, w);
		if (r & 1) res += get_val(--r, w);
		w *= 2;
	}
	return res;
}

int main() {
	int n;
	cin >> n;

	for (int i = 0; i < n - 1; i++) {
		int u, v;
		scanf("%d %d", &u, &v);
		u--;
		v--;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	HL::build();

	update(0, n, 1);

	int Q;
	cin >> Q;
	long long res = 0;
	while (Q--) {
		int u, v;
		scanf("%d %d", &u, &v);
		u--;
		v--;

		HL::for_each(u, v, [&](int l, int r) {
			res += query(l, r + 1);
		});

		HL::for_each(u, v, [&](int l, int r) {
			update(l, r + 1, 1);
		});
	}
	cout << res << endl;
}
0