洛谷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;}
阅读全文
0 0
- 洛谷3261,可并堆打标记
- 左偏树/斜堆/可并堆-洛谷P3377 【模板】左偏树(可并堆)
- HDU1512 可并堆
- 【模板】可并堆
- 可并堆?左偏树?
- 可并堆模板
- 可并堆
- BZOJ 4003([JLOI2015]城池攻占-带标记可合并堆)[Template:带标记可合并堆]
- 左偏树(可并堆)
- HDU1512 左偏树(可并堆)
- 猴子大王 可并堆
- 可并堆之左偏树
- luogu 3377 可并堆
- 【左偏树(可并堆)模板】
- 可并堆与二叉堆
- ZOJ 2334 可并堆<斜堆>
- 【洛谷P3377】【模板】左偏树(可并堆)
- 【洛谷】3377【模板】左偏树(可并堆)
- HBase架构解析二
- UVA 1593
- Linux段错误及GDB Coredump调试方法
- TCP的三次握手和四次挥手
- contest15
- 洛谷3261,可并堆打标记
- git远程协作
- UVA12050
- 将SVN服务器上的数据库数据同步到自己客户端的电脑上(MySQL、Navicat)
- Mysql安装配置
- iOS setDelaysTouchesBegan 详解
- 广搜例题
- gc0329曝光时间设置
- 字母、数字、符号最少两种组合,正则