BZOJ 1036 樹的統計 樹鏈剖分模板

2021-09-12 16:01:45 字數 3381 閱讀 7732

樹上n個點,支援單點修改,區間查詢最大值和sum和。

此處只講大體思路,樹鏈剖分的詳細原理請移步op

[x

]top[x]

top[x]

,即該點的 dfs

dfsdf

s區間修改和區間查詢,就是先處理出兩點之間的樹鏈,由於樹鏈上的點的 dfs

dfsdf

s下面的**包括了區間修改和單點修改,以及區間查詢最大值和最值。

#include

#include

#include

#include

#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)

#define rep(i,a,b) for(int i = a; i <= b; i++)

#define log1(x1,x2) cout << x1 << ": " << x2 << endl;

#define log2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;

typedef

long

long ll;

typedef

double db;

#define int long long

const db eps =

1e-9

;const

int n =

1e5+

100;

using

namespace std;

struct edge e[

2*n]

;struct node t[

2*n]

;int n,m,root,rt,mod,val[n]

,head[n]

,tot,fa[n]

,d[n]

,son[n]

,size[n]

,top[n]

,id[n]

,rk[n]

;//top[x]: x節點所在鏈的頂端節點, id[x]: 節點dfs序, rk[x]: dfs序對應的節點

//val[x]: 每個點初始權值, fa[x]: 每個點父節點, d[x]: 節點深度, size[x]: 節點子樹大小

//rt: 線段樹根節點編號

void

init()

void

add(

int x,

int y)

void

dfs1

(int x)

}void

dfs2

(int x,

int tp)

inline

void

pushup

(int x)

void

build

(int l,

int r,

int x)

int mid =

(l+r)

>>1;

t[x]

.ls =

++tot, t[x]

.rs =

++tot;

build

(l,mid,t[x]

.ls)

,build

(mid+

1,r,t[x]

.rs)

,pushup

(x);

}inline

intlen

(int x)

inline

void

pushdown

(int x)

}void

update

(int l,

int r,

int x,

int c)

pushdown

(x);

int mid =

(t[x]

.l+t[x]

.r)>>1;

if(mid >= l)

update

(l,r,t[x]

.ls,c);if

(mid < r)

update

(l,r,t[x]

.rs,c)

;pushup

(x);

}int

query

(int l,

int r,

int x)

intquery_max

(int l,

int r,

int x)

inline

intsum_maxn

(int x,

int y)

if(id[x]

> id[y]

)swap

(x,y)

;// log2("id[x]",id[x],"id[y]",id[y]);

return

max(ret,

query_max

(id[x]

,id[y]

,rt));

}inline

intsum

(int x,

int y)

if(id[x]

> id[y]

)swap

(x,y)

;return

(ret+

query

(id[x]

,id[y]

,rt));

}inline

void

updates

(int x,

int y,

int c)

if(id[x]

> id[y]

)swap

(x,y)

;update

(id[x]

,id[y]

,rt,c);}

signed

main()

rep(i,

1,n)

scanf

("%lld"

,&val[i]);

scanf

("%lld"

,&m)

; root =1;

tot =0,

dfs1

(root)

,dfs2

(root, root)

; tot =0,

build(1

,n,rt =

++tot)

;rep

(i,1

,m)else

if(op[1]

=='m'

)else

if(op[1]

=='s')}

return0;

}

BZOJ 1036 樹的統計 Count 樹鏈剖分

題目大意 一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 ...

bzoj1036 樹的統計 樹鏈剖分 LCT

ac通道 題解 看到題目,發現是樹剖一眼題,所以就秒掉了。include include include include include include includeusing namespace std typedef long long ll define file read define m...

樹鏈剖分 線段樹 bzoj1036 樹的統計

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...