題目大意:選出k條從葉子節點到根節點的路徑,使路徑上的權值之和最大。注意每個點的權值只能被計算一次。
看到這道題的第一反應是最大費用最大流。對於每條邊只有第一次流的時候有價值。
那麼根據這個思路,我們其實就是每次選取一條權值之和最大的路徑加入答案,因為每個點的權值只能計算一次,所以路徑上的點子樹中所有葉子幾點都要減去這個點的價值,就是用線段樹維護每個點到根的距離。
按照只有葉子節點的dfs序建樹,這樣每次修改就是連續區間了。
#include#include#include#include#include#define ll long long
#define n 400003
using namespace std;
int tot,nxt[n],point[n],v[n],pos[n],l[n],r[n],pd[n],mark[n],sz,n,m,fa[n];
ll tr[n*4],val[n],sum[n],delta[n];
void add(int x,int y)
void dfs(int x,int f)
if (!pd)
l[x]=sz+1;
for (int i=point[x];i;i=nxt[i])
r[x]=sz;
}void update(int
now)
void build(int
now,int l,int r)
intmid=(l+r)/2;
build(now
<<1,l,mid);
build(now
<<1|1,mid+1,r);
update(now);
}void pushdown(int
now)
}void query(int
now,int l,int r,int ll,int rr,ll v)
intmid=(l+r)/2;
pushdown(now);
if (ll<=mid) query(now
<<1,l,mid,ll,rr,v);
if (rr>mid) query(now
<<1|1,mid+1,r,ll,rr,v);
update(now);
}void solve(int x)
}int main()
dfs(1,0);
build(1,1,sz);
ll ans=0;
for (int i=1;i<=m;i++)
printf("%lld\n",ans);
}
BZOJ 3252攻略 dfs序 線段樹
bzoj 3252 攻略 dfs序 線段樹 題目大意 給定一棵以1為根的n個點的樹,樹有點權且點權為正整數,可以選擇k條以根作為起點的路徑,每條路徑的價值即這條路徑上所有點的點權之和。但是選擇一條路徑之後,這條路徑上的所有點的點權會變成0。也就是說,這k條路徑中被重複選擇的點,其點權只能被計算一次 ...
Bzoj3252 攻略(dfs序 線段樹)
題目鏈結 可以想到,每次肯定是拿最大價值為最優 考慮改變樹上乙個點的值,只會影響它的子樹,也就是dfs序上的乙個區間,於是可以以dfs序建線段樹,這樣就變成區間問題了 include include define mid int mid l r 1,ls id 1,rs id 1 1 define ...
bzoj3252攻略 線段樹 dfs序
time limit 10 sec memory limit 128 mb submit 562 solved 238 submit status discuss 題目簡述 樹版 k取方格數 眾所周知,桂木桂馬是攻略之神,開啟攻略之神模式後,他可以同時攻略k部遊戲。今天他得到了一款新遊戲 xx半島 ...