結果

問題 No.900 aδδitivee
ユーザー polylogKpolylogK
提出日時 2019-09-18 22:28:41
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 208 ms / 2,000 ms
コード長 4,614 bytes
コンパイル時間 2,286 ms
コンパイル使用メモリ 181,700 KB
実行使用メモリ 36,648 KB
最終ジャッジ日時 2024-04-14 08:25:37
合計ジャッジ時間 8,597 ms
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,812 KB
testcase_01 AC 2 ms
6,940 KB
testcase_02 AC 2 ms
6,940 KB
testcase_03 AC 2 ms
6,944 KB
testcase_04 AC 2 ms
6,944 KB
testcase_05 AC 2 ms
6,944 KB
testcase_06 AC 2 ms
6,944 KB
testcase_07 AC 207 ms
31,952 KB
testcase_08 AC 207 ms
31,892 KB
testcase_09 AC 203 ms
31,948 KB
testcase_10 AC 202 ms
31,936 KB
testcase_11 AC 203 ms
31,796 KB
testcase_12 AC 206 ms
31,920 KB
testcase_13 AC 206 ms
31,884 KB
testcase_14 AC 203 ms
31,876 KB
testcase_15 AC 208 ms
31,868 KB
testcase_16 AC 207 ms
31,804 KB
testcase_17 AC 206 ms
31,924 KB
testcase_18 AC 204 ms
31,980 KB
testcase_19 AC 202 ms
31,804 KB
testcase_20 AC 203 ms
31,908 KB
testcase_21 AC 205 ms
31,788 KB
testcase_22 AC 182 ms
36,644 KB
testcase_23 AC 184 ms
36,560 KB
testcase_24 AC 182 ms
36,620 KB
testcase_25 AC 183 ms
36,648 KB
testcase_26 AC 183 ms
36,564 KB
testcase_27 AC 187 ms
36,648 KB
testcase_28 AC 187 ms
36,564 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std::literals::string_literals;
using i64 = long long;
using std::cout;
using std::endl;
using std::cin;

template<typename T>
std::vector<T> make_v(size_t a){return std::vector<T>(a);}

template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts){
  return std::vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}

template<typename Monoid, typename OperatorMonoid = Monoid>
class lazy_segment_tree {
	using value_type = Monoid;
	using operator_type = OperatorMonoid;
	using size_type = size_t;

	using F = std::function<value_type (value_type, value_type)>;
	using G = std::function<value_type (value_type, operator_type, int, int)>;
	using H = std::function<operator_type (operator_type, operator_type)>;
	
	size_type size_;
	size_type height_;

	F f;
	G g;
	H h;
	value_type id;
	operator_type id_op;
	std::vector<value_type> data;
	std::vector<operator_type> lazy;
	std::vector<size_type> depth;
	
	const size_type get_height(const size_type& size) const {
		size_type height = 1;
		while(1 << height < size) height++;
		return height;
	}
	const size_type base_size() const {
		return 1 << height_;
	}
	const value_type reflect(const size_type & k) {
		if(lazy[k] == id_op) return data[k];
		int l = (k - (1 << depth[k])) * (base_size() >> depth[k]);
		int r = l + (base_size() >> depth[k]);
		return g(data[k], lazy[k], l, r);
	}
	void eval(const size_type & k) {
		if(lazy[k] == id_op) return;
		lazy[k << 1 ^ 0] = h(lazy[k << 1 ^ 0], lazy[k]);
		lazy[k << 1 ^ 1] = h(lazy[k << 1 ^ 1], lazy[k]);
		data[k] = reflect(k);
		lazy[k] = id_op;
	}
	void thrust(const size_type & k) {
		for(int i = height_; i; i--) eval(k >> i);
	}
	void recalc(size_type k) {
		while(k >>= 1) data[k] = f(reflect(k << 1 ^ 0), reflect(k << 1 ^ 1));
	}
	
	public:
	lazy_segment_tree() {}
	lazy_segment_tree(int n, const F & f, const G & g, const H & h, const value_type & id, const operator_type & id_op) :
		size_(n), f(f), g(g), h(h), id(id), id_op(id_op) {
		height_ = get_height(size_);
		data.assign(base_size() << 1, id);
		lazy.assign(base_size() << 1, id_op);
		depth.assign(base_size() << 1, 0);
		for(int i = 0; i < height_ + 1; i++)
			for(int j = (1 << i); j < (1 << (i + 1)); j++)
				depth[j] = i;
	}
	void update(size_type a, size_type b, operator_type x) {
		thrust(a += base_size());
		thrust(b += base_size() - 1);
		for(size_type l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
			if(l & 1) lazy[l] = h(lazy[l], x), l++;
			if(r & 1) --r, lazy[r] = h(lazy[r], x);
		}
		recalc(a);
		recalc(b);
	}
	void change(size_type k, const value_type x) {
		thrust(k += base_size());
		data[k] = x;
		lazy[k] = id_op;
		recalc(k);
	}
	const value_type fold(size_type a, size_type b) {
		thrust(a += base_size());
		thrust(b += base_size() - 1);

		value_type left_value = id;
		value_type right_value = id;
		for(size_type l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
			if(l & 1) left_value = f(left_value, reflect(l++));
			if(r & 1) right_value = f(reflect(--r), right_value);
		}
		return f(left_value, right_value);
	}

	const value_type operator[](const size_type & k) {
		return fold(k, k + 1);
	}
};

int main() {
	int n; scanf("%d", &n);
	assert(2 <= n and n <= (int)1e5);
	
	std::vector<std::vector<std::pair<int, i64>>> g(n);
	for(int i = 0; i < n - 1; i++) {
		int a, b, c; scanf("%d%d%d", &a, &b, &c);
		assert(0 <= a and a < n);
		assert(0 <= b and b < n);
		assert(0 <= c and c <= (int)1e5);
		
		g[a].push_back({b, c});
		g[b].push_back({a, c});
	}

	std::vector<int> tour, L(n), R(n), task_ikaros;
	auto dfs = [&](auto && dfs, int v, int par) -> void {
		L[v] = tour.size();
		for(auto e: g[v]) {
			if(e.first == par) continue;
			tour.push_back(e.second);
			task_ikaros.push_back(+1);
			dfs(dfs, e.first, v);
			tour.push_back(-e.second);
			task_ikaros.push_back(-1);
		}
		R[v] = tour.size();
	};
	dfs(dfs, 0, -1);

	std::vector<i64> kiritan(task_ikaros.size() + 1, 0);
	for(int i = 0; i < task_ikaros.size(); i++) kiritan[i + 1] = kiritan[i] + task_ikaros[i];
	auto f = [](i64 a, i64 b) { return a + b; };
	auto g_ = [kiritan](i64 a, i64 b, int l, int r) {
		return a + b * (kiritan[r] - kiritan[l]);
	};
	auto h = [](i64 a, i64 b) { return a + b; };	
	lazy_segment_tree<i64, i64> seg(tour.size(), f, g_, h, 0, 0);
	for(int i = 0; i < tour.size(); i++) seg.change(i, tour[i]);
	
	int q; scanf("%d", &q);
	while(q--) {
		int type; scanf("%d", &type);

		if(type == 1) {
			int a, x; scanf("%d%d", &a, &x);

			seg.update(L[a], R[a], x);
		} else if(type == 2) {
			int a; scanf("%d", &a);

			printf("%lld\n", seg.fold(0, L[a]));
		}
	}
	return 0;
}
0