• 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
    ",ans1[i]);
    	for(long long i=1;i<=m;i++)printf("%lld
    ",ans2[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    PO-审批设置
    DIS-接收方式设置入口
    网约车
    汽车租赁
    共享单车
    共享充电宝
    佛教四大名山|道教四大名山|五岳|名山
    我读过的诗词文章书籍
    我看过的电影
    redis异常解决:jedis.exceptions.JedisDataException: ERR Client sent AUTH, but no password is set
  • 原文地址:https://www.cnblogs.com/mybing/p/8436892.html
Copyright © 2020-2023  润新知