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;
}