要求的东西那么多,很显然需要模拟整个过程。不难发现可并堆很好维护,而且也支持打标记。
#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn=300010;
LL rd()
{
LL x=0,f=0;
char c=getchar();
while (c<'0'||c>'9')
{
if (c=='-') f=1;
c=getchar();
}
while (c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return f?-x:x;
}
int root[maxn],lson[maxn],rson[maxn],height[maxn],pass[maxn],
f[maxn],a[maxn],c[maxn],num[maxn],pos[maxn],du[maxn],que[maxn],
n,m;
LL h[maxn],v[maxn],s[maxn],plus[maxn],mul[maxn],val[maxn];
void down(int u)
{
if (!u) return;
if (mul[u]>1)
{
val[u]*=mul[u];
if (lson[u])
{
plus[lson[u]]*=mul[u];
mul[lson[u]]*=mul[u];
}
if (rson[u])
{
plus[rson[u]]*=mul[u];
mul[rson[u]]*=mul[u];
}
mul[u]=1;
}
if (plus[u])
{
val[u]+=plus[u];
if (lson[u]) plus[lson[u]]+=plus[u];
if (rson[u]) plus[rson[u]]+=plus[u];
plus[u]=0;
}
if (pass[u])
{
pos[u]+=pass[u];
if (lson[u]) pass[lson[u]]+=pass[u];
if (rson[u]) pass[rson[u]]+=pass[u];
pass[u]=0;
}
}
void dfs(int u)
{
if (!u) return;
down(u);
dfs(lson[u]);
dfs(rson[u]);
}
int merge(int u,int v)
{
down(u);
down(v);
if (u*v==0) return u+v;
if (val[u]>val[v]) swap(u,v);
rson[u]=merge(rson[u],v);
if (height[rson[u]]>height[lson[u]]) swap(rson[u],lson[u]);
height[u]=height[rson[u]]+1;
return u;
}
int main()
{
int hd=1,tl=0,x;
n=rd();
m=rd();
for (int i=1;i<=n;i++) h[i]=rd();
for (int i=2;i<=n;i++)
{
f[i]=rd();
a[i]=rd();
v[i]=rd();
du[f[i]]++;
}
for (int i=1;i<=m;i++)
{
val[i]=rd();
s[i]=rd();
plus[i]=0;
mul[i]=1;
height[i]=1;
root[s[i]]=merge(root[s[i]],i);
}
for (int i=1;i<=n;i++)
if (!du[i]) que[++tl]=i;
while (hd<=tl)
{
x=que[hd++];
while (root[x])
{
down(root[x]);
if (val[root[x]]<h[x])
{
num[x]++;
root[x]=merge(lson[root[x]],rson[root[x]]);
}
else break;
}
pass[root[x]]++;
if (a[x]) mul[root[x]]*=v[x];
else plus[root[x]]+=v[x];
if (x>1)
{
root[f[x]]=merge(root[f[x]],root[x]);
du[f[x]]--;
if (!du[f[x]]) que[++tl]=f[x];
}
}
dfs(root[1]);
for (int i=1;i<=n;i++) printf("%d\n",num[i]);
for (int i=1;i<=m;i++) printf("%d\n",pos[i]);
}