結果
| 問題 |
No.900 aδδitivee
|
| コンテスト | |
| ユーザー |
Nachia
|
| 提出日時 | 2020-09-27 19:31:35 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 335 ms / 2,000 ms |
| コード長 | 4,103 bytes |
| コンパイル時間 | 1,867 ms |
| コンパイル使用メモリ | 181,500 KB |
| 実行使用メモリ | 24,728 KB |
| 最終ジャッジ日時 | 2024-06-30 12:53:03 |
| 合計ジャッジ時間 | 11,638 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 27 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
#define rep(i,n) for(int i=0; i<(n); i++)
const int xN = 100000;
struct RQ {
struct RQV { LL x, d, z; };
struct RQRV { };
static RQV Zero() { return { 0,0,0 }; }
static RQRV RZero() { return { }; }
// addition
static RQV f(RQV a, RQV b) { return { a.x + b.x + a.d * b.z, a.d + b.d, a.z + b.z }; }
// update function
static void uf(RQV& a, RQV b) { a.d += b.d; }
// effect of range queries n-sized
static void ef(RQV& a, RQRV b, int n) { }
// range query update
static void ruf(RQRV& a, RQRV b) { }
struct Node { RQV v; RQRV r; };
int N;
vector<Node> V;
void init(vector<int> v) {
N = 1; while (N < v.size()) N *= 2;
V.assign(N * 2, { Zero(),RZero() });
rep(i, v.size()) { V[N + i].v.x = v[i]; V[N + i].v.z = 1; }
for (int i = N - 2; i >= 1; i--) V[i].v = f(V[i * 2].v, V[i * 2 + 1].v);
}
void spread(int i, int z) {
ef(V[i].v, V[i].r, z);
if (z != 1) {
ruf(V[i * 2].r, V[i].r);
ruf(V[i * 2 + 1].r, V[i].r);
}
V[i].r = RZero();
}
void upd(int p, RQV v) {
for (int d = N; d >= 1; d /= 2) spread(p / d, d);
p += N; uf(V[p].v, v);
int z = 1;
while (p != 1) {
p /= 2; z *= 2;
spread(p * 2, z / 2); spread(p * 2 + 1, z / 2);
V[p].v = f(V[p * 2].v, V[p * 2 + 1].v);
}
}
void updr(int l, int r, RQRV v, int a = 0, int b = 0, int i = -1) {
if (i == -1) { a = 0; b = N; i = 1; }
if (r <= a || b <= l) { spread(i, b - a); return; }
else if (l <= a && b <= r) { ruf(V[i].r, v); spread(i, b - a); return; }
spread(i, b - a);
updr(l, r, v, a, (a + b) / 2, i * 2);
updr(l, r, v, (a + b) / 2, b, i * 2 + 1);
V[i].v = f(V[i * 2].v, V[i * 2 + 1].v);
}
RQV query(int l, int r, int a = 0, int b = 0, int i = -1) {
if (i == -1) { a = 0; b = N; i = 1; }
if (r <= a || b <= l) return Zero();
spread(i, b - a);
if (l <= a && b <= r) return V[i].v;
RQV q1 = query(l, r, a, (a + b) / 2, i * 2);
RQV q2 = query(l, r, (a + b) / 2, b, i * 2 + 1);
q1 = f(q1, q2);
return q1;
}
};
int N;
vector<int> E[xN];
int hlZ[xN], hlL[xN];
int hlH[xN], hlP[xN];
int hlR[xN];
int hlRP = 0;
RQ hlG;
void DFS(int p) {
int x = -1;
for (int e : E[p]) {
if (hlP[p] == e) continue;
hlP[e] = p;
DFS(e);
hlZ[p] += hlZ[e];
if (x == -1) x = e; else if (hlZ[x] < hlZ[e]) x = e;
}
if (x != -1) { hlH[x] = p; hlL[p] = hlL[x] + 1; }
}
void hlDFS(int p) {
if (hlH[p] != p) {
hlR[p] = hlR[hlP[p]] + 1;
hlH[p] = hlH[hlP[p]];
}
else {
hlR[p] = hlRP;
hlRP += hlL[p] + 1;
}
for (int e : E[p]) {
if (hlP[p] == e) continue;
hlDFS(e);
}
}
vector<pair<pair<int, int>, int>> J;
void hlInit() {
rep(i, N) { hlH[i] = i; hlP[i] = -1; hlZ[i] = 1; hlL[i] = 0; }
DFS(0);
hlDFS(0);
vector<int> rqI(N);
for (auto& j : J) {
int u = j.first.first, v = j.first.second;
int w = j.second;
if (hlP[u] == v) swap(u, v);
rqI[hlR[v]] = w;
}
hlG.init(rqI);
}
void hlAdd(int p, LL x) {
hlG.upd(hlR[p], { 0,x,0 });
}
LL hlQuery(int p) {
RQ::RQV ans = RQ::Zero();
while (p != -1) {
ans = RQ::f(hlG.query(hlR[hlH[p]], hlR[p] + 1), ans);
p = hlP[hlH[p]];
}
return ans.x;
}
int main() {
cin >> N;
J.resize(N - 1);
rep(i, N - 1) {
int u, v, w; cin >> u >> v >> w;
E[u].push_back(v);
E[v].push_back(u);
J[i] = { {u,v},w };
}
hlInit();
int Q; cin >> Q;
while (Q--) {
int c; cin >> c;
if (c == 1) {
int a, x; cin >> a >> x;
hlAdd(a, x);
}
if (c == 2) {
int a; cin >> a;
cout << hlQuery(a) << endl;
}
}
return 0;
}
Nachia