結果
| 問題 |
No.900 aδδitivee
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-09-18 22:11:08 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,608 bytes |
| コンパイル時間 | 2,004 ms |
| コンパイル使用メモリ | 186,732 KB |
| 実行使用メモリ | 36,736 KB |
| 最終ジャッジ日時 | 2024-10-03 05:30:37 |
| 合計ジャッジ時間 | 10,164 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | WA * 2 |
| other | WA * 14 RE * 13 |
ソースコード
#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);
if(r & 1) 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;
}