码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4003: [JLOI2015]城池攻占 左偏树

时间:2018-02-09 23:51:30      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:long   dfs   return   ace   its   getchar   head   insert   push   

对于每个节点做一次左偏树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;
}

  

bzoj4003: [JLOI2015]城池攻占 左偏树

标签:long   dfs   return   ace   its   getchar   head   insert   push   

原文地址:https://www.cnblogs.com/mybing/p/8436892.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!