• BZOJ3252攻略


    BZOJ3252攻略

    题面:BZOJ

    解析

    博主从前在考场上做到过类似的题,当时并没有做出来。今天总算解决了,其实现在想来挺简单的,就是个简单的贪心,然后用线段树维护一下就行了。

    代码

    
    #include<cstdio>
    #define N 200005
    #define LL long long
    #define mid ((l+r)>>1)
    #define lc c[u][0]
    #define rc c[u][1]
    using namespace std;
    inline int In(){
    	char c=getchar(); int x=0,ft=1;
    	for(;c<'0'||c>'9';c=getchar()) if(c=='-') ft=-1;
    	for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
    	return x*ft;
    }
    inline LL max(LL a,LL b){
    	return a>b?a:b;
    }
    int n,K,val[N],h[N],e_tot=0;
    struct E{ int to,nex; }e[N<<1];
    inline void add(int u,int v){
    	e[++e_tot]=(E){v,h[u]}; h[u]=e_tot;
    	e[++e_tot]=(E){u,h[v]}; h[v]=e_tot;
    }
    int dfn[N],low[N],rk[N],fa[N],dfs_clock=0;
    LL d[N],ans=0;
    void dfs(int u,int pre){
    	int child=0;
    	d[u]=d[pre]+val[u]; fa[u]=pre;
    	dfn[u]=++dfs_clock; rk[dfs_clock]=u;
    	for(int i=h[u],v;i;i=e[i].nex){
    		v=e[i].to; if(v!=fa[u]) dfs(v,u);
    		++child;
    	}
    	low[u]=dfs_clock;
    }
    int rt=0,T_tot=0,c[N<<1][2],pos[N<<1];
    LL _mx[N<<1],lz[N<<1];
    inline void PushUp(int u){
    	_mx[u]=max(_mx[lc],_mx[rc]);
    	pos[u]=pos[c[u][_mx[u]!=_mx[lc]]];
    }
    inline void PushDown(int u){
    	if(lz[u]){
    		lz[lc]+=lz[u]; _mx[lc]+=lz[u];
    		lz[rc]+=lz[u]; _mx[rc]+=lz[u]; lz[u]=0;
    	}
    }
    inline void Build(int l,int r,int& u){
    	if(!u) u=++T_tot;
    	if(l==r){ _mx[u]=d[rk[l]]; pos[u]=rk[l]; return; }
    	Build(l,mid,lc); Build(mid+1,r,rc); PushUp(u);
    }
    inline void Modify(int L,int R,int C,int l,int r,int u){
    	if(L<=l&&r<=R){ _mx[u]+=C; lz[u]+=C; return; }
    	PushDown(u);
    	if(L<=mid) Modify(L,R,C,l,mid,lc);
    	if(R>mid) Modify(L,R,C,mid+1,r,rc);
    	PushUp(u);
    }
    bool flag[N];
    int main(){
    	n=In(); K=In(); flag[0]=1;
    	for(int i=1;i<=n;++i) val[i]=In();
    	for(int i=1;i<n;++i) add(In(),In());
    	dfs(1,0); Build(1,n,rt);
    	for(int i=1;i<=K;++i){
    		ans+=_mx[rt];
    		for(int u=pos[rt];!flag[u];u=fa[u]){
    			flag[u]=1;
    			Modify(dfn[u],low[u],-val[u],1,n,rt);
    		}
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
    
  • 相关阅读:
    前言(CSDN也有Markdown了,好开森)
    One usage of recurison: the tower of Hanoi
    使用Android注解来改善代码
    mysql生产环境____主从同步修复案例
    不同类型的指针
    C++ 对象模型
    为什么需要模版成员方法
    理解 traits
    C++ 异常处理
    传const引用代替传值
  • 原文地址:https://www.cnblogs.com/pkh68/p/10555014.html
Copyright © 2020-2023  润新知