对于 100% 的数据,1 <= n;m <= 300000; 1 <= fi<i; 1 <= ci <= n; -10^18 <= hi,vi,si <= 10^18;ai等于1或者2;当 ai =1 时,vi > 0;保证任何时候骑士战斗力值的绝对值不超过 10^18。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=300010;
typedef long long ll;
int n,m;
int ch[maxn][2],nvl[maxn],k[maxn],next[maxn],head[maxn],hh[maxn],nn[maxn],dep[maxn],p[maxn],q[maxn],rt[maxn];
ll h[maxn],s[maxn],ts[maxn],tc[maxn],v[maxn];
void pushdown(int x)
{
if(tc[x])
{
if(ch[x][0]) tc[ch[x][0]]*=tc[x],ts[ch[x][0]]*=tc[x],s[ch[x][0]]*=tc[x];
if(ch[x][1]) tc[ch[x][1]]*=tc[x],ts[ch[x][1]]*=tc[x],s[ch[x][1]]*=tc[x];
tc[x]=1;
}
if(ts[x])
{
if(ch[x][0]) ts[ch[x][0]]+=ts[x],s[ch[x][0]]+=ts[x];
if(ch[x][1]) ts[ch[x][1]]+=ts[x],s[ch[x][1]]+=ts[x];
ts[x]=0;
}
}
int merge(int x,int y)
{
pushdown(x),pushdown(y);
if(!x) return y;
if(!y) return x;
if(s[x]>s[y]) swap(x,y);
ch[x][1]=merge(ch[x][1],y);
if(nvl[ch[x][0]]<nvl[ch[x][1]]) swap(ch[x][0],ch[x][1]);
nvl[x]=nvl[ch[x][1]]+1;
return x;
}
void dfs(int x)
{
int i;
for(i=hh[x];i;i=nn[i]) rt[x]=merge(rt[x],i),q[i]=dep[x];
for(i=head[x];i;i=next[i])
{
dep[i]=dep[x]+1;
dfs(i);
rt[x]=merge(rt[x],rt[i]);
}
while(rt[x]&&s[rt[x]]<h[x])
{
q[rt[x]]-=dep[x],p[x]++;
rt[x]=merge(ch[rt[x]][0],ch[rt[x]][1]);
}
if(!rt[x]) return ;
if(k[x]) s[rt[x]]*=v[x],tc[rt[x]]*=v[x];
else s[rt[x]]+=v[x],ts[rt[x]]+=v[x];
}
int main()
{
scanf("%d%d",&n,&m);
nvl[0]=-1;
int i,a;
for(i=1;i<=n;i++) scanf("%lld",&h[i]);
for(i=2;i<=n;i++) scanf("%d%d%lld",&a,&k[i],&v[i]),next[i]=head[a],head[a]=i;
for(i=1;i<=m;i++) scanf("%lld%d",&s[i],&a),nn[i]=hh[a],hh[a]=i,tc[i]=1;
dep[1]=1,dfs(1);
for(i=1;i<=n;i++) printf("%d\n",p[i]);
for(i=1;i<=m;i++) printf("%d\n",q[i]);
return 0;
}