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\n",ans);
	return 0;
}


posted @ 2019-03-18 21:11  pkh68  阅读(188)  评论(0编辑  收藏  举报