P
a
r
t
0
Part_0
Part0:吐槽 还是欠练啊,上来就是个大根堆直接
T
T
T飞。 PS:高三学科狗,暑假来划水
p
a
r
t
1
part_1
part1:思路 将骑士看做堆的元素,树上每个节点看做一个(小根)堆。 初始化后,从叶子出发,一路向上模拟。 对于节点
P
P
P,先将其孩子的堆与之合并,然后去掉牺牲的骑士并计入答案,接着更新活着的其数值(打标记); 标记:
l
a
z
y
1
lazy1
lazy1:乘法 ;
l
a
z
y
2
lazy2
lazy2:加法 ;
l
a
z
y
3
lazy3
lazy3:骑士攻克城堡数
p
a
r
t
2
part_2
part2:注意 开
l
o
n
g
l
o
n
g
long long
longlong 乘加标记的处理顺序 最后处理掉一号节点中堆的答案标记
代码
#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define IL inline#define ll long longusingnamespace std;
IL ll read(){
ll sum =0;bool f =0;char c =getchar();for(;'0'> c || c >'9'; c =getchar())if(c =='-') f =1;for(;'0'<= c && c <='9'; c =getchar())
sum = sum *10+(c -'0');return f ?-sum : sum;}constintN(300005),M(300005);//lazy1: mul ; lazy2 : add ; lazy3 : mark2int ch[M][2], dis[M], lazy3[M];
ll val[M], lazy1[M], lazy2[M];int point[N];// 节点i的堆首bool parm1[N];
ll def[N], parm2[N];int head[N];int cnt, nxt[N], to[N];int mark1[N], mark2[M];// 牺牲 ; 攻占
IL voidAdd(int u,int v){
nxt[++cnt]= head[u]; to[cnt]= v; head[u]= cnt;}
IL voidClean(int u){int v;if(lazy1[u]){if((v = ch[u][0])){ lazy1[v]*= lazy1[u]; lazy2[v]*= lazy1[u]; val[v]*= lazy1[u];}if((v = ch[u][1])){ lazy1[v]*= lazy1[u]; lazy2[v]*= lazy1[u]; val[v]*= lazy1[u];}
lazy1[u]=1;}if(lazy2[u]){if((v = ch[u][0])){ lazy2[v]+= lazy2[u]; val[v]+= lazy2[u];}if((v = ch[u][1])){ lazy2[v]+= lazy2[u]; val[v]+= lazy2[u];}
lazy2[u]=0;}if(lazy3[u]){if((v = ch[u][0])){ lazy3[v]+= lazy3[u]; mark2[v]+= lazy3[u];}if((v = ch[u][1])){ lazy3[v]+= lazy3[u]; mark2[v]+= lazy3[u];}
lazy3[u]=0;}}
IL intMerge(int x,int y){if(!x)return y;if(!y)return x;Clean(x);Clean(y);if(val[x]> val[y])swap(x, y);
ch[x][1]=Merge(ch[x][1], y);if(dis[ch[x][0]]< dis[ch[x][1]])swap(ch[x][0], ch[x][1]);
dis[x]= dis[ch[x][1]]+1;return x;}
IL voidSolve(int u,int p){for(; u && val[u]< def[p];){Clean(u);++mark1[p];
u =Merge(ch[u][0], ch[u][1]);}
point[p]= u;++lazy3[u];++mark2[u];if(parm1[p]){
lazy1[u]*= parm2[p]; lazy2[u]*= parm2[p]; val[u]*= parm2[p];}else{
lazy2[u]+= parm2[p]; val[u]+= parm2[p];}}
IL voidDfs(int u){for(int i = head[u], v; i; i = nxt[i]){
v = to[i];Dfs(v);if(point[v]) point[u]=Merge(point[u], point[v]);}if(point[u])Solve(point[u], u);}
IL voidGet_2(int u){if(lazy3[u]){int v;if((v = ch[u][0])){ lazy3[v]+= lazy3[u]; mark2[v]+= lazy3[u];}if((v = ch[u][1])){ lazy3[v]+= lazy3[u]; mark2[v]+= lazy3[u];}
lazy3[u]=0;}if(ch[u][0])Get_2(ch[u][0]);if(ch[u][1])Get_2(ch[u][1]);}intmain(){int n =read(), m =read();for(int i =1; i <= n;++i) def[i]=read();for(int i =2; i <= n;++i){Add(read(), i);
parm1[i]=read(); parm2[i]=read();}for(int i =1, tmp; i <= m;++i){
lazy1[i]=1;
val[i]=read();
tmp =read();if(!point[tmp]) point[tmp]= i;else point[tmp]=Merge(point[tmp], i);}Dfs(1);Get_2(point[1]);for(int i =1; i <= n;++i)printf("%d\n", mark1[i]);for(int i =1; i <= m;++i)printf("%d\n", mark2[i]);return0;}