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

Posted mybing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

  

以上是关于bzoj4003: [JLOI2015]城池攻占 左偏树的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ4003JLOI2015城池攻占

[BZOJ4003][JLOI2015]城池攻占

bzoj4003[JLOI2015]城池攻占 可并堆

BZOJ4003 JLOI2015城池攻占

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

BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆