这题网上题解到处都是。
但有一个关键处
void dfs(int x,int fa){
dep[x]=dep[fa]+1;
for(int i=h[x];i;i=e[i].next){
int y=e[i].to;
dfs(y,x);
r[x]=merge(r[x],r[y]);
}
while(r[x] && a[r[x]].v<hh[x]){
++ans1[x];
ans2[r[x]]=dep[c[r[x]]]-dep[x];
pop(r[x]);
}
if(aa[x] && r[x])cov(r[x],vv[x],0);
else cov(r[x],1,vv[x]);
}
void dfs(int x,int fa){
dep[x]=dep[fa]+1;
for(int i=h[x];i;i=e[i].next){
int y=e[i].to;
dfs(y,x);
while(r[x] && a[r[x]].v<hh[x]){
++ans1[x];
ans2[r[x]]=dep[c[r[x]]]-dep[x];
pop(r[x]);
}
r[x]=merge(r[x],r[y]);
}
if(aa[x] && r[x])cov(r[x],vv[x],0);
else cov(r[x],1,vv[x]);
}
这两份代码那个对哪个错?答案是第一个对。因为第二个会让叶子结点的骑士活下来(鸣谢ww140142)
#pra\
gma GCC optimize("O2")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1000005;
int xb,r[maxn],h[maxn],n,m,i,c[maxn],ans1[maxn],ans2[maxn],dep[maxn],aa[maxn],y;
LL hh[maxn],vv[maxn],s[maxn],x;
struct node{
int l,r,d;
LL ch,ji,v;//cheng,jia
node(LL _v=0):v(_v){
l=r=d=ji=0;
ch=1;
}
bool operator>(const node&rhs){
return v>rhs.v;
}
bool operator<(const node&rhs){
return v<rhs.v;
}
}a[maxn];
void cov(int i,LL x,LL y){
if(!i)return;
a[i].v*=x;
a[i].v+=y;
a[i].ch*=x;
a[i].ji*=x;
a[i].ji+=y;
}
void pushdown(int i){
cov(a[i].l,a[i].ch,a[i].ji);
cov(a[i].r,a[i].ch,a[i].ji);
a[i].ch=1;
a[i].ji=0;
}
int merge(int x,int y){
if(!x || !y)return x|y;
pushdown(x);
pushdown(y);
if(a[x]>a[y])swap(x,y);
a[x].r=merge(a[x].r,y);
if(a[a[x].r].d>a[a[x].l].d)swap(a[x].l,a[x].r);
if(a[x].r)a[x].d=a[a[x].r].d+1;
else a[x].d=0;
return x;
}
struct edge{
int to,next;
edge(int _to=0,int _next=0):to(_to),next(_next){}
}e[maxn];
void addedge(int x,int y){
e[++xb]=edge(y,h[x]);
h[x]=xb;
}
void pop(int&x){
pushdown(x);
x=merge(a[x].l,a[x].r);
}
void dfs(int x,int fa){
dep[x]=dep[fa]+1;
for(int i=h[x];i;i=e[i].next){
int y=e[i].to;
dfs(y,x);
r[x]=merge(r[x],r[y]);
}
while(r[x] && a[r[x]].v<hh[x]){
++ans1[x];
ans2[r[x]]=dep[c[r[x]]]-dep[x];
pop(r[x]);
}
if(aa[x] && r[x])cov(r[x],vv[x],0);
else cov(r[x],1,vv[x]);
}
inline int getint(){
int x=0,y=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-')y=-1;
c=getchar();
}
for(;isdigit(c);c=getchar())x=x*10+c-48;
return x*y;
}
inline LL getl(){
LL x=0,y=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-')y=-1;
c=getchar();
}
for(;isdigit(c);c=getchar())x=x*10+c-48;
return x*y;
}
int buf[100];
inline void putint(int x){
if(!x)putchar('0');
else{
int xb=0;
for(;x;x/=10)buf[++xb]=x%10;
for(;xb;--xb)putchar(buf[xb]+48);
}
}
int main(){
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i)hh[i]=getl();
for(i=2;i<=n;++i){
y=getint();
aa[i]=getint();
vv[i]=getl();
addedge(y,i);
}
for(i=1;i<=m;++i){
x=getl();
c[i]=getint();
a[i]=node(x);
r[c[i]]=merge(r[c[i]],i);
}
dfs(1,0);
while(r[1]){
ans2[r[1]]=dep[c[r[1]]];
pop(r[1]);
}
for(i=1;i<=n;++i)putint(ans1[i]),putchar('\n');
for(i=1;i<=m;++i)putint(ans2[i]),putchar('\n');
return 0;
}