HAOI2015 樹上操作 樹鏈剖分

2021-08-09 08:46:10 字數 2639 閱讀 8383

1963. [haoi2015]樹上操作

有一棵點數為n的樹,以點1為根,且樹點有權值。然後有m個操作,分為三種:

操作1:把某個節點x的點權增加a。

操作2:把某個節點x為根的子樹中所有點的點權都增加a。

操作3:詢問某個節點x到根的路徑中所有點的點權和。

第一行兩個整數n,m,表示點數和運算元。

接下來一行n個整數,表示樹中節點的初始權值。

接下來n-1行每行兩個正整數fr,to,表示該樹中存在一條邊(fr,to)。

再接下來m行,每行分別表示一次操作。其中第乙個數表示該操作的種類(1~3),之後接這個操作的引數(x或者x a)。

對於每個詢問操作,輸出該詢問的答案。答案之間用換行隔開。

5 51 2 3 4 5

1 21 4

2 32 5

3 31 2 1

3 52 1 2

3 3對於30%的資料,n,m<=1000

對於50%的資料,n,m<=100000且資料隨機。

對於100%的資料,n,m<=100000,且所有輸入資料的絕對值都不會超過10^6。

注意long long就好了 

把它當做樹剖模板來做,聽說並查集也能做

1 #include 2 #include 3

4 typedef long

long

ll;5

6const

int maxn=100010;7

8int

n,m,inr;910

ll a[maxn];

1112

struct

segmenttree ;

16 segmenttree t[maxn<<2

];17

18struct

data ;

22 data e[maxn*10

];23

24int head[maxn<<1

],tot;

2526

intsiz[maxn],son[maxn],fa[maxn],id[maxn],dep[maxn],top[maxn],rank[maxn],mx[maxn];

2728 inline void read(int&x)

3435 inline void readl(ll&x)

4142 inline void add(int x,int

y) 47

48 inline int max(int a,int

b) 51

52 inline void swap(int&x,int&y)

5657 inline void dfs_1(int now,int

f) 68}69

70 inline void dfs_2(int now,int

sym)

81return;82

}8384 inline void build_tree(int now,int l,int

r) 90

int mid=(l+r)>>1

;91 build_tree(now<<1

,l,mid);

92 build_tree(now<<1|1,mid+1

,r);

93 t[now].val=t[now<<1].val+t[now<<1|1

].val;94}

9596 inline void down(int

now)

103104 inline void modify(int now,int l,int

r,ll val)

110down(now);

111int mid=(t[now].l+t[now].r)>>1

;112

if(l<=mid) modify(now<<1

,l,r,val);

113if(r>mid) modify(now<<1|1

,l,r,val);

114 t[now].val=t[now<<1].val+t[now<<1|1

].val;

115}

116117 inline ll query(int now,int l,int

r) 126

127 inline ll pre_query(int u,int

v) 134

if(dep[u]

135 ans+=query(1

,id[v],id[u]);

136return

ans;

137}

138139

inthh()

149 dfs_1(1,0

);150 dfs_2(1,1

);151 build_tree(1,1

,inr);

152ll p;

153for(register int i=1;i<=m;++i)

159else

if(opt==2

) 163

else

167}

168return0;

169}

170171

int sb=hh();

172int main()

**

HAOI2015 樹上操作 樹鏈剖分

有一棵點數為n的樹,以點1為根,且樹點有權值。然後有m個操作,分為三種 操作1 把某個節點x的點權增加a。操作2 把某個節點x為根的子樹中所有點的點權都增加a。操作3 詢問某個節點x到根的路徑中所有點的點權和。第一行兩個整數n,m,表示點數和運算元。接下來一行n個整數,表示樹中節點的初始權值。接下來...

HAOI2015 樹上操作

題目描述 有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數...

HAOI2015 樹上操作

有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數和運算元。...