bzoj4003: [JLOI2015]城池攻占 左偏树
对于每个节点做一次左偏树dfs就好了,记得加标记。
#include<bits/stdc++.h> using namespace std; long long a[300010],q[300100],c[300010],v[300010],n,m,h[300010],d[300010],ans1[300010],ans2[300010],lin[300010],lin2[300010],tot=0,qtree[300100],f[300100],s[300010],len=0,len2=0; struct one{ long long y,v,next,v2; }; one e[300010]; one e2[301000]; struct tr{ long long l,r,v,lazy1,lazy2,id,d; }; tr tree[300100]; inline long long read(){ long long x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();} return x*f; } void getdeep(){ q[1]=0; int head=0,tail=1; while(head++<tail){ for(long long i=lin[q[head]];i;i=e[i].next){ d[e[i].y]=d[q[head]]+1; q[++tail]=e[i].y; } } } inline void insert(long long x,long long y){e[++len].next=lin[x];lin[x]=len;e[len].y=y;} inline void insert2(long long x,long long y){e2[++len2].next=lin2[x];lin2[x]=len2;e2[len2].y=y;} void newpoint(long long p){ tree[++tot].v=s[p]; tree[tot].id=p; tree[tot].d=1; tree[tot].lazy1=1; tree[tot].lazy2=0; } inline void pushdown(long long p){ tree[tree[p].l].lazy1*=tree[p].lazy1; tree[tree[p].l].lazy2*=tree[p].lazy1; tree[tree[p].l].lazy2+=tree[p].lazy2; tree[tree[p].r].lazy1*=tree[p].lazy1; tree[tree[p].r].lazy2*=tree[p].lazy1; tree[tree[p].r].lazy2+=tree[p].lazy2; tree[p].v=tree[p].v*tree[p].lazy1+tree[p].lazy2; tree[p].lazy1=1; tree[p].lazy2=0; } inline long long merge(long long k1,long long k2){ if(k1==0||k2==0)return k1+k2; if(tree[k1].v*tree[k1].lazy1+tree[k1].lazy2>tree[k2].v*tree[k2].lazy1+tree[k2].lazy2)swap(k1,k2); pushdown(k1); tree[k1].r=merge(tree[k1].r,k2); if(tree[tree[k1].l].d<tree[tree[k1].r].d)swap(tree[k1].l,tree[k1].r); tree[k1].d=tree[tree[k1].r].d+1; return k1; } long long dfs(long long p){ for(long long i=lin2[p];i;i=e2[i].next){ newpoint(e2[i].y); if(i==lin2[p])qtree[p]=tot; else qtree[p]=merge(qtree[p],tot); } for(long long i=lin[p];i;i=e[i].next) if(qtree[p])qtree[p]=merge(dfs(e[i].y),qtree[p]); else qtree[p]=dfs(e[i].y); while(tree[qtree[p]].v*tree[qtree[p]].lazy1+tree[qtree[p]].lazy2<h[p]&&qtree[p]){ ans1[p]++; ans2[tree[qtree[p]].id]=d[c[tree[qtree[p]].id]]-d[p]; pushdown(qtree[p]); qtree[p]=merge(tree[qtree[p]].l,tree[qtree[p]].r); } if(a[p])tree[qtree[p]].lazy1*=v[p],tree[qtree[p]].lazy2*=v[p]; else tree[qtree[p]].lazy2+=v[p]; return qtree[p]; } int main(){ n=read();m=read();insert(0,1); h[0]=1000000000000000002; for(long long i=1;i<=n;i++)h[i]=read(); for(long long i=2;i<=n;i++){f[i]=read();a[i]=read();v[i]=read();insert(f[i],i);} for(long long i=1;i<=m;i++){s[i]=read();c[i]=read();insert2(c[i],i);} getdeep();dfs(0); for(long long i=1;i<=n;i++)printf("%lld\n",ans1[i]); for(long long i=1;i<=m;i++)printf("%lld\n",ans2[i]); return 0; }