description
給出一棵有向樹,有點權和邊權,定義乙個節點i的答案為以i為根的子樹中有多少j的點權不小於j->i的簡單路徑上邊權和,求所有點的答案
input
第一行一整數t表示用例組數,每組用例首先輸入樹上點數n,之後n個整數x[i]表示第i個點的點權,最後n-1行每行三個整數u,v,w表示樹上一條邊u-v的邊權是w,樹根是1(1<=n<=5e5,1<=x[i],w<=1e9)
對於每個點,其貢獻是對從自身開始往上一段連續的父親節點每個點的答案加一,實時維護乙個1~i的邊權字首和sum[j]以及對應的編號id[j],假設從根節點1到節點i有res個節點,那麼所有sum[j]>=sum[res]-x[i]的j都是i能夠貢獻到的點,假設最小的滿足條件的j是pos,pos可以對sum陣列二分搜尋得到,那麼i節點的貢獻就是在樹上對id[pos],id[pos+1],…,i這條邊每個節點的答案加一,類似字首和優化,cnt[fa[id[pos]]]–,cnt[i]++,這樣以來在往下深搜的時候把每個點的貢獻記錄下來,在回溯的時候將兒子節點的cnt累加到父親節點上即得到所有點的答案
#include#include#include
using
namespace
std;
const
int maxm = 5e5 + 5
;typedef
long
long
ll;ll w[maxm], sum[maxm];
intpa[maxm], id[maxm], cnt[maxm];
intt;
intn;
struct
edge ;
};vector
ve[maxm];
intres;
void dfs(int u, int
p) }
intmain()
pa[1] = 0, id[0] = 1, sum[0] = 0
; res = 1
; dfs(
1, 1
);
for(int i = 1; i <= n; i++)
}return0;
}
再來一道線段樹的題。
b 單點更新2 time limit 3000msmemory limit 32768kb64bit io format i64d i64u submit status description 很多學校流行一種比較的習慣。老師們很喜歡詢問,從某某到某某當中,分數最高的是多少。這讓很多學生很反感。不管...
種樹(一道簡單的差分約束系統)
為了綠化鄉村,h村積極響應號召,開始種樹了。h村里有n幢房屋,這些屋子的排列順序很有特點,在一條直線上。於是方便起見,我們給它們標上1 n。樹就種在房子前面的空地上。同時,村民們向村長提出了m個意見,每個意見都是按如下格式 希望第li個房子到第ri個房子的房前至少有ci棵樹。因為每個房屋前的空地面積...
線段樹 博弈 一道博弈題
障礙點數和詢問點數都是1e5 座標範圍為1e9 實際資料既然有大於1e9的 乙個點的下方或左邊存在必敗點,則為必勝點,否則為必敗點 同一行的障礙會把這一行分成很多段,段與段之間是互不影響的。考慮同一段的點,若其中乙個點為必敗點,則之後的點一定是必勝點,也就是說要找到第乙個必敗點 但是有很多行,直接列...