BZOJ_3252_Strategy_Line segment tree+dfs sequence

BZOJ_3252_Strategy_Line segment tree+dfs sequence

Description

Topic description: tree version [k takes the number of squares]
As we all know, Guimu Guima is the God of Raiders. After turning on the God of Raiders mode, he can attack k games at the same time. Today he got a new game "XX
Peninsula", this game has n scenes, some scenes can reach other scenes through different selection branches. All scenes and selection branches form a tree
Structure: Start the game at the root node (common line), and the leaf node is the ending. Each scene has a value, and now Guima opens the God of Raiders mode, with the same
When you play the game k times, ask him the value of the scene he watched and the maximum value (the same scene cannot be repeated many times to get the value)
"Why do you know the value of each scene before you even play it?"
"I've seen the end."

Input

The first line contains two positive integers n,k
The second line contains n positive integers representing the value of each scene
The following n-1 lines, each line contains 2 integers a, b, indicating that scene a has an alternative branch leading to scene b (that is, a is the father of b)
Make sure that scene 1 is the root node
n<=200000, 1<=scene value<=2^31-1

Output

output an integer representing the answer

Sample Input

5 2
4 3 2 1 1
1 2
1 5
2 3
2 4

Sample Output

10

There is a classic network flow practice for k to take the number of squares.
Since the network flow is augmented by finding the longest path based on greed, placing it on the tree is transformed into k times of querying the root-to-leaf path point weight and the largest leaf number.
Then subtract the contribution of the points on the path.
Since each point is deleted at most once, the contribution of one chain can be modified at a time by violently going up each time.
You can get the dfs sequence of the leaves, and each modification corresponds to a section modification.
The line segment tree can maintain the maximum value of the interval.
 
Code:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 200050
#define ls p<<1
#define rs p<<1|1
typedef long long ll;
int mx[N<<2];
ll t[N<<2],inc[N<<2],ans;
int head[N],to[N<<1],nxt[N<<1],val[N],cnt,kill[N],dfn[N],son[N],k,tot,fa[N],turn[N],n;
ll dis[N],dd[N];
inline void add(int u,int v) {
    to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void dfs(int x,int y) {
    dis[x]=dis[y]+val[x];
    int i, flg = 0; fa [x] = y;
    dfn[x]=tot+1;
    for(i=head[x];i;i=nxt[i]) {
        if(to[i]!=y) flg=1;
    }
    if(!flg) {
        dfn[x]=son[x]=++tot;
        turn[tot]=x;
        return ;
    }
    dfn[x]=tot+1;
    for(i=head[x];i;i=nxt[i]) {
        if(to[i]!=y) {
            dfs(to[i],x);
        }
    }
    sound[x]=tot;
}
void pushup(int p) {
    if(t[ls]>t[rs]) mx[p]=mx[ls],t[p]=t[ls];
    else mx[p]=mx[rs],t[p]=t[rs];
}
void build(int l,int r,int p) {
    if(l==r) {
        mx[p]=turn[l];
        t[p]=dis[turn[l]];
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,ls); build(mid+1,r,rs);
    pushup(p);
}
void pushdown(int p) {
    ll d=inc[p];
    if(d) {
        t[ls]+=d; t[rs]+=d;
        inc[ls]+=d; inc[rs]+=d;
        inc[p]=0;
    }
}
void update(int l,int r,int x,int y,int v,int p) {
    if(x<=l&y>=r) {
        t[p]+=v; inc[p]+=v; return ;
    }
    pushdown(p);
    int mid=(l+r)>>1;
    if(x<=mid) update(l,mid,x,y,v,ls);
    if(y>mid) update(mid+1,r,x,y,v,rs);
    pushup(p);
}
void solve(int x) {
    if(kill[x]||!x) return ;
    kill[x]=1;
    update(1,tot,dfn[x],son[x],-val[x],1);
    solve(fa[x]);
}
int main() {
    scanf("%d%d",&n,&k);
    int i,x,y;
    for(i=1;i<=n;i++) {
        scanf("%d",&val[i]);
    }
    for(i=1;i<n;i++) {
        scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
    }
    dfs(1,0);
    build(1,tot,1);
    for(i=1;i<=k;i++) {
        ans+=t[1];
        solve(mx[1]);
    }
    printf("%lld\n",ans);
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325471920&siteId=291194637