洛谷3261,可并堆打标记

来源:互联网 发布:北塔软件规模 编辑:程序博客网 时间:2024/05/18 01:35

这题网上题解到处都是。
但有一个关键处

void dfs(int x,int fa){    dep[x]=dep[fa]+1;    for(int i=h[x];i;i=e[i].next){        int y=e[i].to;        dfs(y,x);        r[x]=merge(r[x],r[y]);    }    while(r[x] && a[r[x]].v<hh[x]){        ++ans1[x];        ans2[r[x]]=dep[c[r[x]]]-dep[x];        pop(r[x]);    }    if(aa[x] && r[x])cov(r[x],vv[x],0);        else cov(r[x],1,vv[x]);}
void dfs(int x,int fa){    dep[x]=dep[fa]+1;    for(int i=h[x];i;i=e[i].next){        int y=e[i].to;        dfs(y,x);        while(r[x] && a[r[x]].v<hh[x]){            ++ans1[x];            ans2[r[x]]=dep[c[r[x]]]-dep[x];            pop(r[x]);        }        r[x]=merge(r[x],r[y]);    }    if(aa[x] && r[x])cov(r[x],vv[x],0);        else cov(r[x],1,vv[x]);}

这两份代码那个对哪个错?答案是第一个对。因为第二个会让叶子结点的骑士活下来(鸣谢ww140142)

#pra\gma GCC optimize("O2")#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn=1000005;int xb,r[maxn],h[maxn],n,m,i,c[maxn],ans1[maxn],ans2[maxn],dep[maxn],aa[maxn],y;LL hh[maxn],vv[maxn],s[maxn],x;struct node{    int l,r,d;    LL ch,ji,v;//cheng,jia    node(LL _v=0):v(_v){        l=r=d=ji=0;        ch=1;    }    bool operator>(const node&rhs){        return v>rhs.v;    }    bool operator<(const node&rhs){        return v<rhs.v;    }}a[maxn];void cov(int i,LL x,LL y){    if(!i)return;    a[i].v*=x;    a[i].v+=y;    a[i].ch*=x;    a[i].ji*=x;    a[i].ji+=y;}void pushdown(int i){    cov(a[i].l,a[i].ch,a[i].ji);    cov(a[i].r,a[i].ch,a[i].ji);    a[i].ch=1;    a[i].ji=0;}int merge(int x,int y){    if(!x || !y)return x|y;    pushdown(x);    pushdown(y);    if(a[x]>a[y])swap(x,y);    a[x].r=merge(a[x].r,y);    if(a[a[x].r].d>a[a[x].l].d)swap(a[x].l,a[x].r);    if(a[x].r)a[x].d=a[a[x].r].d+1;        else a[x].d=0;    return x;}struct edge{    int to,next;    edge(int _to=0,int _next=0):to(_to),next(_next){}}e[maxn];void addedge(int x,int y){    e[++xb]=edge(y,h[x]);    h[x]=xb;}void pop(int&x){    pushdown(x);    x=merge(a[x].l,a[x].r);}void dfs(int x,int fa){    dep[x]=dep[fa]+1;    for(int i=h[x];i;i=e[i].next){        int y=e[i].to;        dfs(y,x);        r[x]=merge(r[x],r[y]);    }    while(r[x] && a[r[x]].v<hh[x]){        ++ans1[x];        ans2[r[x]]=dep[c[r[x]]]-dep[x];        pop(r[x]);    }    if(aa[x] && r[x])cov(r[x],vv[x],0);        else cov(r[x],1,vv[x]);}inline int getint(){    int x=0,y=1;    char c=getchar();    while(!isdigit(c)){        if(c=='-')y=-1;        c=getchar();    }    for(;isdigit(c);c=getchar())x=x*10+c-48;    return x*y;}inline LL getl(){    LL x=0,y=1;    char c=getchar();    while(!isdigit(c)){        if(c=='-')y=-1;        c=getchar();    }    for(;isdigit(c);c=getchar())x=x*10+c-48;    return x*y;}int buf[100];inline void putint(int x){    if(!x)putchar('0');        else{            int xb=0;            for(;x;x/=10)buf[++xb]=x%10;            for(;xb;--xb)putchar(buf[xb]+48);        }}int main(){    scanf("%d%d",&n,&m);    for(i=1;i<=n;++i)hh[i]=getl();    for(i=2;i<=n;++i){        y=getint();        aa[i]=getint();        vv[i]=getl();        addedge(y,i);    }    for(i=1;i<=m;++i){        x=getl();        c[i]=getint();        a[i]=node(x);        r[c[i]]=merge(r[c[i]],i);    }    dfs(1,0);    while(r[1]){        ans2[r[1]]=dep[c[r[1]]];        pop(r[1]);    }    for(i=1;i<=n;++i)putint(ans1[i]),putchar('\n');    for(i=1;i<=m;++i)putint(ans2[i]),putchar('\n');    return 0;}
原创粉丝点击