可并堆。打标记。
注意细节。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> #define maxv 300500 #define maxe 300500 using namespace std; struct edge { long long v,nxt; }e[maxe]; set <long long> s[maxv]; set <long long> ::iterator it; long long n,m,h[maxv],fath[maxv],a[maxv],v[maxv],w[maxv],c[maxv],val[maxv]; long long tree[maxv][3],dfl[maxv],dis[maxv],nume=0,l1[maxv],l2[maxv]; long long ans1[maxv],ans2[maxv],top[maxv],g[maxv]; bool vis[maxv]; void addedge(long long u,long long v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } void pushdown(long long x) { long long ls=tree[x][1],rs=tree[x][2]; l1[ls]=l1[ls]*l2[x]+l1[x]; l1[rs]=l1[rs]*l2[x]+l1[x]; l2[ls]*=l2[x]; l2[rs]*=l2[x]; val[ls]=val[ls]*l2[x]+l1[x]; val[rs]=val[rs]*l2[x]+l1[x]; l1[x]=0;l2[x]=1; } void pushup(long long x) { long long ls=tree[x][1],rs=tree[x][2]; if (dfl[ls]<dfl[rs]) swap(tree[x][1],tree[x][2]); if (rs==0) dfl[x]=0; else dfl[x]=dfl[rs]+1; } long long merge(long long a,long long b) { if (a==0) return b; if (b==0) return a; if (val[a]>val[b]) swap(a,b); pushdown(a); tree[a][2]=merge(tree[a][2],b); pushup(a); return a; } long long pop(long long x) { long long ls=tree[x][1],rs=tree[x][2]; pushdown(x); tree[x][1]=0;tree[x][2]=0; return merge(ls,rs); } void dfs1(long long x) { for (long long i=g[x];i;i=e[i].nxt) { long long v=e[i].v; dis[v]=dis[x]+1; dfs1(v); } } void dfs2(long long x) { for (long long i=g[x];i;i=e[i].nxt) dfs2(e[i].v); long long root=-1; for (it=s[x].begin();it!=s[x].end();it++) { long long now=*it; if (root==-1) root=now; else root=merge(root,now); } for (long long i=g[x];i;i=e[i].nxt) { long long v=e[i].v; if (top[v]<=0) continue; if (root==-1) root=top[v]; else root=merge(root,top[v]); } long long cnt=0; while ((val[root]<h[x]) && (root>=1)) { ans2[root]=dis[c[root]]-dis[x]; vis[root]=true; root=pop(root); cnt++; } ans1[x]=cnt; if (a[x]==0) {l1[root]+=v[x];val[root]+=v[x];} else {l2[root]*=v[x];l1[root]*=v[x];val[root]*=v[x];} top[x]=root; } int main() { memset(vis,false,sizeof(vis)); scanf("%lld%lld",&n,&m); fill(l2+1,l2+m+1,1); for (long long i=1;i<=n;i++) scanf("%lld",&h[i]); for (long long i=2;i<=n;i++) { scanf("%lld%lld%lld",&fath[i],&a[i],&v[i]); addedge(fath[i],i); } for (long long i=1;i<=m;i++) { scanf("%lld%lld",&w[i],&c[i]); s[c[i]].insert(i); val[i]=w[i]; } dfs1(1); dfs2(1); for (long long i=1;i<=n;i++) printf("%lld ",ans1[i]); for (long long i=1;i<=m;i++) { if ((ans2[i]==0) && (vis[i]==false)) printf("%lld ",dis[c[i]]+1); else printf("%lld ",ans2[i]); } return 0; }