樹上求和( dfs序 線段樹 )

2021-10-04 08:54:42 字數 2166 閱讀 8360

題目鏈結

解題報告:

將樹轉化成dfs序,對於任意節點及其子樹總是一段連續的區間,那麼轉化成區間問題。

( ai + b ) ^2 = ai*ai + 2*ai*b + b*b 很明顯線段樹維護即可。

#define first f

#define second s

#define ll long long

#define mp make_pair

#define pb push_back

#define pf push_front

#define lb lower_bound

#define ub upper_bound

#include

#define pii pair

#define mem(a,b) memset(a,b,sizeof(a))

using

namespace std;

const

int maxn=

1e5+5;

const

int inf=

0x3f3f3f3f

;const

int mod=

23333

;const

double pi=

acos(-

1);const

double e=

2.718281828459

;pii edge[maxn<<1]

;int laz1[maxn<<2]

,sum1[maxn<<2]

,sum2[maxn<<2]

;int in[maxn]

,out[maxn]

,head[maxn]

,a[maxn]

,dfn[maxn]

;int cnt=

0,knt=0;

void

add(

int from,

int to)

void

dfs(

int now,

int pre)

dfs(to,now);}

out[now]

=knt;

}void

pushup

(int rt)

void

pushdown

(int l,

int r,

int rt)

}void

build

(int l,

int r,

int rt)

int mid=

(l+r)

>>1;

build

(l,mid,rt<<1)

;build

(mid+

1,r,rt<<1|

1);pushup

(rt);}

void

update

(int l,

int r,

int l,

int r,

int rt,

int val)

int mid=

(l+r)

>>1;

pushdown

(l,r,rt);if

(l<=mid)

if(r>mid)

pushup

(rt);}

intquery

(int l,

int r,

int l,

int r,

int rt)

int mid=

(l+r)

>>1;

pushdown

(l,r,rt)

;int ans=0;

if(l<=mid)

if(r>mid)

return ans;

}int

main()

dfs(1,

-1);

build(1

,n,1);

while

(q--

)else

}return0;

}

nefu 1330 樹上求和dfs序 線段樹

dfs序即先序遍歷樹,對於第乙個節點進行總結點個數加一並且賦值操作。思路 對於給出的點,進行vecter建樹。建樹完成後dfs序求出各節點,dfs序,ls i 表示當前節點的dfs序為多少,rs i 表示以當前節點為根的子樹的最右邊節點值。include include include includ...

求和(dfs序 線段樹)

題意 已知有n個節點,有n 1條邊,形成乙個樹的結構。給定乙個根節點k,每個節點都有乙個權值,節點i的權值為vi 給m個操作,操作有兩種型別 1 a x 表示將節點a的權值加上x 2 a 表示求a節點的子樹上所有節點的和 包括a節點本身 題解 dfs序 線段樹 用dfs序確定in x 和out x ...

樹上求和(dfs

有一棵包含n個節點和n 1條邊的樹,規定樹鏈 u,v 為樹上從u到v的簡單路徑。樹的每條邊上都有乙個正整數,這個正整數被稱作這條邊的顏色,規定一條樹鏈的權值w u,v 為這條樹鏈上所有邊的顏色的代數和。而整棵樹的權值為所有不同的樹鏈的權值的代數和。已知所有邊的顏色集合恰好為1到n 1這n 1個不同的...