题目
在dfs的过程中把所有能到达这个城池的骑士用可并堆存储。
然后把不能通过该城池的弹走。
堆上打标记真是666.
加个快读快了10倍。。。。
#include<bits/stdc++.h>
#define maxn 300005
#define LL long long
using namespace std;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res){
char ch;bool f = 0;
for(;!isdigit(ch=getc());) if(ch=='-') f=1;
for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
(f) && (res=-res);
}
int n,m,f[maxn],ch[maxn][2];
LL h[maxn],a[maxn],v[maxn],s[maxn],add[maxn],mul[maxn];
vector<int>G[maxn];
int info[maxn],Prev[maxn<<1],to[maxn<<1],cnt_e;
void Node(int u,int v){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v; }
int rt[maxn],d[maxn];
int ans1[maxn],ans2[maxn],adda[maxn];
void dt(int x){
if(add[x] || mul[x]!=1){
s[x] = s[x] * mul[x] + add[x];
if(ch[x][0])
mul[ch[x][0]] *= mul[x] , add[ch[x][0]] *= mul[x] , add[ch[x][0]] += add[x];
if(ch[x][1])
mul[ch[x][1]] *= mul[x] , add[ch[x][1]] *= mul[x] , add[ch[x][1]] += add[x];
add[x] = 0 , mul[x] = 1;
}
if(adda[x]){
ans2[x] += adda[x];
if(ch[x][0]) adda[ch[x][0]] += adda[x];
if(ch[x][1]) adda[ch[x][1]] += adda[x];
adda[x] = 0;
}
}
void merge(int &now,int u,int v){
dt(u) , dt(v);
if(!u || !v){now = u|v; return;}
else if(s[u] < s[v]) now = u , merge(ch[now][1],ch[u][1],v);
else now = v , merge(ch[now][1],u,ch[v][1]);
if(d[ch[now][1]] > d[ch[now][0]]) swap(ch[now][1],ch[now][0]);
d[now] = d[ch[now][1]] + 1;
}
void dfs(int now,int ff){
for(int i=0,siz=G[now].size();i<siz;i++)
merge(rt[now],rt[now],G[now][i]);
for(int i=info[now];i;i=Prev[i])
if(to[i]!=ff){
dfs(to[i],now);
merge(rt[now],rt[now],rt[to[i]]);
}
for(;rt[now] && s[rt[now]] < h[now];dt(rt[now]),merge(rt[now],ch[rt[now]][0],ch[rt[now]][1]))
ans1[now] ++;
adda[rt[now]]++,add[rt[now]]+=a[now],mul[rt[now]]*=v[now];
}
void dfs(int now){
if(!now) return;
dt(now);
dfs(ch[now][0]),dfs(ch[now][1]);
}
int main(){
read(n),read(m);
for(int i=1;i<=n;i++) read(h[i]);
for(int i=2;i<=n;i++)
{
read(f[i]),read(a[i]),read(v[i]),Node(f[i],i);
if(a[i] == 0) a[i] = v[i] , v[i] = 1;
else a[i] = 0;
}
for(int i=1;i<=m;i++)
{
mul[i]=1;
int c;
read(s[i]),read(c);
G[c].push_back(i);
}
dfs(1,0);
for(int i=1;i<=n;i++)
printf("%d\n",ans1[i]);
dfs(rt[1]);
for(int i=1;i<=m;i++)
printf("%d\n",ans2[i]);
}