樹鏈差分的一道題

2022-05-23 22:30:11 字數 1107 閱讀 4677

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的 乙個點的下方或左邊存在必敗點,則為必勝點,否則為必敗點 同一行的障礙會把這一行分成很多段,段與段之間是互不影響的。考慮同一段的點,若其中乙個點為必敗點,則之後的點一定是必勝點,也就是說要找到第乙個必敗點 但是有很多行,直接列...