如题,cin 和 cout 是快读实现的,没放出来
#define N 300005
using i64 = long long;
struct sakuya {
i64 s;
i64 id;
i64 start;
bool operator<(const sakuya& a) {
return s < a.s;
}
bool operator>(const sakuya& a) {
return s > a.s;
}
};
struct Node {
Node *child, *nex;
sakuya val;
i64 plus, mul; // 加后乘
Node() {
mul = 1;
}
void push_down() {
Node* c = child;
val.s *= mul;
val.s += plus;
while (c->val.s != 0) {
if (mul) {
c->mul *= mul;
c->plus *= plus;
}
if (plus) {
c->plus += plus;
}
c = c->nex;
}
mul = 1, plus = 0;
}
} space[N];
Node *tot = space + 1, *null = space;
Node* meld(Node* x, Node* y) {
if (x == null)
return y;
else if (y == null)
return x;
x->push_down();
y->push_down();
if (x->val > y->val) {
x->nex = y->child;
y->child = x;
return y;
} else {
y->nex = x->child;
x->child = y;
return x;
}
}
Node* merge(Node* nod) {
if (nod == null || nod->nex == null) return nod;
Node *x = nod->nex, *y = nod->nex->nex;
x->nex = nod->nex = null;
x->push_down();
y->push_down();
nod->push_down();
return meld(merge(y), meld(nod, x));
}
void push(Node*& root, sakuya val) {
Node* y = ++tot;
y->val = val;
y->child = y->nex = null;
if (root == null) {
root = y;
return;
}
root->push_down();
root = meld(root, y);
}
void pop(Node*& root) {
Node* t = merge(root->child);
root->child = root->nex = null;
root->mul = 1;
root->plus = 0;
root->val = { 0, 0, 0 };
root = t;
}
i64 son[N], nex[N]; // 左儿子右兄弟
i64 op[N], val[N];
i64 hp[N];
Node* heap[N];
i64 kill[N], guard[N];
i64 dep[N];
i64 n, m;
i64 t1, t2, t3;
void dfs(int nod) {
// if (heap[nod] == null) return;
for (int to = son[nod]; to; to = nex[to]) {
dep[to] = dep[nod] + 1;
dfs(to);
if (heap[to] != null) {
heap[to]->child = merge(heap[to]->child); // 多配对几次防止 push_down 复杂度爆炸
heap[to]->push_down(); // 标记下传
heap[nod] = meld(heap[nod], heap[to]); // 合并
heap[nod]->child = merge(heap[nod]->child);
}
}
heap[nod]->push_down();
while (heap[nod] != null && heap[nod]->val.s < hp[nod]) {
++guard[nod]; // 当前城池杀人 + 1
kill[heap[nod]->val.id] = dep[heap[nod]->val.start] - dep[nod]; // 起点深度 - 终点深度
pop(heap[nod]);
heap[nod]->push_down();
}
// 添加标记
if (op[nod]) {
heap[nod]->mul *= val[nod];
heap[nod]->plus *= val[nod];
} else {
heap[nod]->plus += val[nod];
}
}
void last(Node* nod) { // 统计最后一个堆的节点
if (nod == null) return;
kill[nod->val.id] = dep[nod->val.start]; // 起点深度 - 终点深度
last(nod->nex);
last(nod->child);
}
int main() {
dep[1] = 1;
null->child = null->nex = null;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> hp[i];
heap[i] = null;
}
for (int i = 2; i <= n; ++i) {
cin >> t1 >> op[i] >> val[i];
nex[i] = son[t1];
son[t1] = i;
}
for (int i = 1; i <= m; ++i) {
cin >> t1 >> t2; // 初始攻击力,初始位置
push(heap[t2], (sakuya){ t1, i, t2 });
}
dfs(1);
last(heap[1]);
for (int i = 1; i <= n; ++i) {
cout << guard[i] << endl;
}
for (int i = 1; i <= m; ++i) {
cout << kill[i] << endl;
}
return 0;
}