JLOI2015 城池攻占
额...左偏树(可并堆)。
两件事情,1:需要用到lazy标记(左偏树是二叉数据结构,可以PushDown)2.用到lazy标记时,注意先乘后加(在打标记的时候修改加法标记)
剩下的,就是dfs模拟(有一些奇怪的OJ会发生爆栈的鬼畜事情)
维护小根堆,以能到达这个节点的骑士的战斗力为排序基准
之后每次删除不能满足的节点,剩下的就是类板子了,可以放心食用
递归版
1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 #include <cstring> 5 #include <cstdlib> 6 #include <queue> 7 #include <iostream> 8 using namespace std; 9 #define N 300005 10 #define ll long long 11 struct node 12 { 13 int ls,rs,dis;ll x,add,mul; 14 }mp[N<<1]; 15 struct no 16 { 17 int to,next; 18 }e[N]; 19 ll h[N],v[N]; 20 int head[N],cnt,fa[N],dep[N],a[N],siz[N],ans[N],s[N],n,m; 21 void add(int x,int y) 22 { 23 e[cnt].to=y; 24 e[cnt].next=head[x]; 25 head[x]=cnt++; 26 return ; 27 } 28 void PushDown(int x) 29 { 30 if(mp[x].mul!=1) 31 { 32 mp[mp[x].ls].x*=mp[x].mul; 33 mp[mp[x].rs].x*=mp[x].mul; 34 mp[mp[x].ls].mul*=mp[x].mul; 35 mp[mp[x].rs].mul*=mp[x].mul; 36 mp[mp[x].ls].add*=mp[x].mul; 37 mp[mp[x].rs].add*=mp[x].mul; 38 mp[x].mul=1; 39 } 40 if(mp[x].add) 41 { 42 if(mp[x].ls) 43 mp[mp[x].ls].x+=mp[x].add,mp[mp[x].ls].add+=mp[x].add; 44 if(mp[x].rs) 45 mp[mp[x].rs].x+=mp[x].add,mp[mp[x].rs].add+=mp[x].add; 46 mp[x].add=0; 47 } 48 } 49 int merge(int x,int y) 50 { 51 if(!x)return y; 52 if(!y)return x; 53 if(mp[x].x>mp[y].x)swap(x,y); 54 PushDown(x); 55 mp[x].rs=merge(mp[x].rs,y); 56 if(mp[mp[x].rs].dis>mp[mp[x].ls].dis)swap(mp[x].ls,mp[x].rs); 57 mp[x].dis=mp[mp[x].rs].dis+1; 58 return x; 59 } 60 void dfs(int x,int from) 61 { 62 for(int i=head[x];i!=-1;i=e[i].next) 63 { 64 int to1=e[i].to; 65 dep[to1]=dep[x]+1; 66 dfs(to1,x); 67 int fx=fa[x],fy=fa[to1]; 68 fa[x]=merge(fx,fy); 69 } 70 if(!fa[x])return ; 71 int fx=fa[x]; 72 while(mp[fx].x<h[x]) 73 { 74 PushDown(fx); 75 fa[x]=merge(mp[fx].ls,mp[fx].rs); 76 siz[x]++; 77 ans[fx]=dep[s[fx]]-dep[x]; 78 if(!fa[x])return; 79 fx=fa[x]; 80 } 81 if(a[x]) 82 { 83 mp[fx].x*=v[x]; 84 mp[fx].mul*=v[x]; 85 mp[fx].add*=v[x]; 86 }else 87 { 88 mp[fx].x+=v[x]; 89 mp[fx].add+=v[x]; 90 } 91 return ; 92 } 93 int main() 94 { 95 memset(head,-1,sizeof(head)); 96 memset(ans,-1,sizeof(ans)); 97 scanf("%d%d",&n,&m); 98 for(int i=1;i<=n;i++)scanf("%lld",&h[i]); 99 for(int i=2;i<=n;i++) 100 { 101 int x; 102 scanf("%d%d%lld",&x,&a[i],&v[i]); 103 add(x,i); 104 } 105 for(int i=1;i<=m;i++) 106 { 107 ll x; 108 scanf("%lld%d",&x,&s[i]); 109 mp[i].x=x; 110 mp[i].mul=1; 111 int fx=fa[s[i]]; 112 fa[s[i]]=merge(fx,i); 113 } 114 dfs(1,0); 115 for(int i=1;i<=n;i++) 116 { 117 printf("%d\n",siz[i]); 118 } 119 for(int i=1;i<=m;i++) 120 { 121 printf("%d\n",(ans[i]==-1)?(dep[s[i]]+1):ans[i]); 122 } 123 return 0; 124 }
非递归版
1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 #include <cstring> 5 #include <cstdlib> 6 #include <queue> 7 #include <iostream> 8 using namespace std; 9 #define N 300005 10 #define ll long long 11 struct node 12 { 13 int ls,rs,dis;ll x,add,mul; 14 }mp[N<<1]; 15 struct no 16 { 17 int to,next; 18 }e[N]; 19 ll h[N],v[N]; 20 int head[N],cnt,fa[N],dep[N],a[N],siz[N],ans[N],s[N],n,m; 21 void add(int x,int y) 22 { 23 e[cnt].to=y; 24 e[cnt].next=head[x]; 25 head[x]=cnt++; 26 return ; 27 } 28 void PushDown(int x) 29 { 30 if(mp[x].mul!=1) 31 { 32 mp[mp[x].ls].x*=mp[x].mul; 33 mp[mp[x].rs].x*=mp[x].mul; 34 mp[mp[x].ls].mul*=mp[x].mul; 35 mp[mp[x].rs].mul*=mp[x].mul; 36 mp[mp[x].ls].add*=mp[x].mul; 37 mp[mp[x].rs].add*=mp[x].mul; 38 mp[x].mul=1; 39 } 40 if(mp[x].add) 41 { 42 if(mp[x].ls) 43 mp[mp[x].ls].x+=mp[x].add,mp[mp[x].ls].add+=mp[x].add; 44 if(mp[x].rs) 45 mp[mp[x].rs].x+=mp[x].add,mp[mp[x].rs].add+=mp[x].add; 46 mp[x].add=0; 47 } 48 } 49 int merge(int x,int y) 50 { 51 if(!x)return y; 52 if(!y)return x; 53 if(mp[x].x>mp[y].x)swap(x,y); 54 PushDown(x); 55 mp[x].rs=merge(mp[x].rs,y); 56 if(mp[mp[x].rs].dis>mp[mp[x].ls].dis)swap(mp[x].ls,mp[x].rs); 57 mp[x].dis=mp[mp[x].rs].dis+1; 58 return x; 59 } 60 int f[N]; 61 void dfs(int x) 62 { 63 f[1]=0; 64 while(x) 65 { 66 int son=0; 67 for(int i=head[x];i!=-1;i=e[i].next) 68 { 69 int to1=e[i].to; 70 if(to1!=f[x]) 71 { 72 f[to1]=x; 73 dep[to1]=dep[x]+1; 74 head[x]=e[i].next; 75 x=to1; 76 son=1; 77 break; 78 } 79 } 80 if(!son) 81 { 82 if(!fa[x]) 83 { 84 x=f[x]; 85 continue; 86 } 87 int fx=fa[x]; 88 while(mp[fx].x<h[x]) 89 { 90 PushDown(fx); 91 fa[x]=merge(mp[fx].ls,mp[fx].rs); 92 siz[x]++; 93 ans[fx]=dep[s[fx]]-dep[x]; 94 fx=fa[x]; 95 if(!fx)break; 96 } 97 if(!fx) 98 { 99 x=f[x]; 100 continue; 101 } 102 if(a[x]) 103 { 104 mp[fx].x*=v[x]; 105 mp[fx].mul*=v[x]; 106 mp[fx].add*=v[x]; 107 }else 108 { 109 mp[fx].x+=v[x]; 110 mp[fx].add+=v[x]; 111 } 112 fx=fa[f[x]]; 113 int fy=fa[x]; 114 fa[f[x]]=merge(fx,fy); 115 x=f[x]; 116 } 117 } 118 return ; 119 } 120 int main() 121 { 122 memset(head,-1,sizeof(head)); 123 memset(ans,-1,sizeof(ans)); 124 scanf("%d%d",&n,&m); 125 for(int i=1;i<=n;i++)scanf("%lld",&h[i]); 126 for(int i=2;i<=n;i++) 127 { 128 int x; 129 scanf("%d%d%lld",&x,&a[i],&v[i]); 130 add(x,i); 131 } 132 for(int i=1;i<=m;i++) 133 { 134 ll x; 135 scanf("%lld%d",&x,&s[i]); 136 mp[i].x=x; 137 mp[i].mul=1; 138 int fx=fa[s[i]]; 139 fa[s[i]]=merge(fx,i); 140 } 141 dfs(1); 142 for(int i=1;i<=n;i++) 143 { 144 printf("%d\n",siz[i]); 145 } 146 for(int i=1;i<=m;i++) 147 { 148 printf("%d\n",(ans[i]==-1)?(dep[s[i]]+1):ans[i]); 149 } 150 return 0; 151 }
bfs版没有写...