bzoj3252攻略 線段樹 dfs序

2022-04-06 02:10:14 字數 2313 閱讀 1661

time limit: 10 sec  memory limit: 128 mb

submit: 562  solved: 238

[submit][status][discuss]

題目簡述:樹版[k取方格數]

眾所周知,桂木桂馬是攻略之神,開啟攻略之神模式後,他可以同時攻略k部遊戲。

今天他得到了一款新遊戲《xx半島》,這款遊戲有n個場景(scene),某些場景可以通過不同的選擇支到達其他場景。所有場景和選擇支構成樹狀結構:開始遊戲時在根節點(共通線),葉子節點為結局。每個場景有乙個價值,現在桂馬開啟攻略之神模式,同時攻略k次該遊戲,問他觀賞到的場景的價值和最大是多少(同一場景**多次是不能重複得到價值的)

「為什麼你還沒玩就知道每個場景的價值呢?」

「我已經看到結局了。」

第一行兩個正整數n,k

第二行n個正整數,表示每個場景的價值

以下n-1行,每行2個整數a,b,表示a場景有個選擇支通向b場景(即a是b的父親)

保證場景1為根節點

輸出乙個整數表示答案

5 24 3 2 1 1

1 21 5

2 32 4

10對於100%的資料,n<=200000,1<=場景價值<=2^31-1

dfs序+線段樹

/*

嗯,需要維護每個點到根的距離。

首先開始的時候選取葉子結點一定比中間節點優。

當選擇了一條鏈的時候,會對哪些點有影響呢?

答案當然是在這條鏈上的點的子樹。把這個點的子樹權值減掉這個點的權值就好。

看到子樹,想到dfs序。又因為要查詢最大值,所以可以想到用線段樹實現。

線段樹每個節點維護原樹每個點到根的距離的最大值和原樹每個節點dfs序所對應的點的編號。

每次查詢區間最大值,然後刪去這條鏈,每次刪的時候更新子樹權值(區間減法)。

刪除把這個點的權值賦值為0就好。然後往上走,走的時候到某個點權值為0那麼就停。

因為如果某個點權值為0,那麼他到根的路徑上所有點權都為零。恩。

*/#include

#include

#include

#define n 200007

#define ll long long

using

namespace

std;

ll n,m,ans,cnt,tot;

ll head[n],dis[n],fa[n];

ll s[n],pos[n],t[n],a[n];

struct

edgee[n

<<1

];struct

treetr[n

<<2

];namespace

seg

void pushdown(int

k)

void build(int k,int l,int

r)

int mid=l+r>>1

; build(k

<<1,l,mid);build(k<<1|1,mid+1

,r);

pushup(k);

}void update(int k,int l,int r,int

z)

pushdown(k);

int mid=tr[k].l+tr[k].r>>1

;

if(r<=mid) update(k<<1

,l,r,z);

else

if(l>mid) update(k<<1|1

,l,r,z);

else update(k<<1,l,mid,z),update(k<<1|1,mid+1

,r,z);

pushup(k);

}}using

namespace

seg;

inline

void add(int u,int

v)inline ll read()

while(c>='

0'&&c<='9')

return x*f;

}void dfs(int u,int

last,ll sum)

t[u]=tot;

}void change(intu)}

intmain()

ans=a[1];a[1]=0;dfs(1,0,0

); build(

1,1,n);

while(m--)

printf(

"%lld\n

",ans);

return0;

}

BZOJ 3252攻略 dfs序 線段樹

bzoj 3252 攻略 dfs序 線段樹 題目大意 給定一棵以1為根的n個點的樹,樹有點權且點權為正整數,可以選擇k條以根作為起點的路徑,每條路徑的價值即這條路徑上所有點的點權之和。但是選擇一條路徑之後,這條路徑上的所有點的點權會變成0。也就是說,這k條路徑中被重複選擇的點,其點權只能被計算一次 ...

bzoj 3252 攻略 (線段樹 DFS序)

題目大意 選出k條從葉子節點到根節點的路徑,使路徑上的權值之和最大。注意每個點的權值只能被計算一次。看到這道題的第一反應是最大費用最大流。對於每條邊只有第一次流的時候有價值。那麼根據這個思路,我們其實就是每次選取一條權值之和最大的路徑加入答案,因為每個點的權值只能計算一次,所以路徑上的點子樹中所有葉...

Bzoj3252 攻略(dfs序 線段樹)

題目鏈結 可以想到,每次肯定是拿最大價值為最優 考慮改變樹上乙個點的值,只會影響它的子樹,也就是dfs序上的乙個區間,於是可以以dfs序建線段樹,這樣就變成區間問題了 include include define mid int mid l r 1,ls id 1,rs id 1 1 define ...