SPOJ6779 樹剖 區間最大連續和

2021-09-25 08:37:34 字數 3619 閱讀 5064

給定一棵樹,有n(n

≤100000

)n(n≤100000)

n(n≤10

0000

)個節點,每乙個節點都有乙個權值xi(

∣xi∣

≤10000

)x_i (|x_i| \le 10000)

xi​(∣x

i​∣≤

1000

0)你需要執行q(q

≤100000))

q (q \le 100000))

q(q≤10

0000

))次操作:

1 11a

aab

bb 查詢(a,

b)

(a,b)

(a,b

)這條鏈上的最大子段和,可以為空(即輸出000)

2 22a

aabbbc

cc 將(a,

b)

(a,b)

(a,b

)這條鏈上的所有點權變為ccc(

∣c∣≤

10000

)(|c| \le 10000)

(∣c∣≤1

0000

)相較於spo

j1716

spoj1716

spoj17

16,變化就是從普通區間變到了樹上,然後是區間修改(其實沒差)。多用了乙個樹鏈剖分。

樹鏈剖分部分和普通的也有一些區別,就是要分別記錄左右兩條鏈的資訊,最後再合併才能得到最終答案,假設x

xx是左鏈,y

yy是右鏈就可。最後合併的時候還要注意一點:兩個鏈的方向是相反的,也就是說這兩個鏈的左右連續區間是方向是相反的,要交換其中乙個的順序再合併得出最終答案。

#include

using

namespace std;

typedef

long

long ll;

typedef

unsigned

long

long ull;

typedef pair<

int,

int> pii;

const

int maxn =

4e5+5;

const

int maxm =

100+5;

const

int inf =

0x3f3f3f3f

;const ll mod =

1e9+7;

//19260817

const

double pi =

acos(-

1.0)

;int n, q, x, y, z, cnt, tot, opt, head[maxn]

, w[maxn]

;int id[maxn]

, pre[maxn]

, son[maxn]

, size[maxn]

, deep[maxn]

, top[maxn]

, nw[maxn]

;struct nodeedge[maxn <<1]

;struct qwq

}a[maxn <<2]

;qwq pushup

(qwq x, qwq y)

void

pushdown

(int k,

int l,

int r,

int mid)

}void

build

(int k,

int l,

int r)

int mid = l + r >>1;

build

(k <<

1, l, mid)

;build

(k <<1|

1, mid +

1, r)

; a[k]

=pushup

(a[k <<1]

, a[k <<1|

1]);

}qwq query

(int k,

int l,

int r,

int x,

int y)

int mid = l + r >>1;

pushdown

(k, l, r, mid)

; qwq p, q;

if(x <= mid) p =

query

(k <<

1, l, mid, x, y);if

(y > mid) q =

query

(k <<1|

1, mid +

1, r, x, y)

;return

pushup

(p, q);}

void

update

(int k,

int l,

int r,

int x,

int y,

int z)

int mid = l + r >>1;

pushdown

(k, l, r, mid);if

(x <= mid)

update

(k <<

1, l, mid, x, y, z);if

(y > mid)

update

(k <<1|

1, mid +

1, r, x, y, z)

; a[k]

=pushup

(a[k <<1]

, a[k <<1|

1]);

}void

addedge

(int u,

int v)

void

dfs1

(int x,

int f,

int d)

}void

dfs2

(int x,

int topf)

}qwq querysum

(int x,

int y)

else}if

(deep[x]

> deep[y]

)else

swap

(l.lw, l.rw)

;return

pushup

(l, r);}

void

updatesum

(int x,

int y,

int z)

if(deep[x]

> deep[y]

)swap

(x, y)

;update(1

,1, n, id[x]

, id[y]

, z);}

intmain()

dfs1(1

,-1,

1);dfs2(1

,1);

build(1

,1, n)

;scanf

("%d"

,&q)

;while

(q--

)else

if(opt ==2)

}return0;

}

**巨醜

線段樹區間最大連續子段和

線段樹多維護三個值 當前區間從左端開始最大連續和cl,從右端開始最大連續和cr,區間內最大連續和m cl等於max 左子區間和s 右子區間cl,左子區間cl cr等於max 右子區間和s 左子區間cr,右子區間cr m等於max 左子區間m,右子區間m,左子區間cr 右子區間cl 查詢時返回區間段並...

最大連續環區間和 dp

200 ms 最大連續區間和有兩種情況,1是不跨界 2是跨界 對於不跨界,我們dp求一次就得到不跨界的最大和 對於跨界的,我們反過來想,除去跨界的最大連續和後 剩下的必然是最小連續和,而且 必定小於等於0 否則的話把其首尾加到最大連續序列中,得到的值比原最大值大,矛盾 因此,我們先求最小連續和,然後...

HDU 1540 線段樹 區間合併 最大連續區間)

做kuangbin線段樹專題的時候遇到的題目,感覺這是一道非常有趣的題目。線段樹的題目做的比較少,沒有見過這種通過線段樹在區間上做文章的題目,感覺做完這個題目之後加深了對線段樹左右孩子所覆蓋的區間之間的關係的認識。題意 1 n個地道,m個次操作,d代表摧毀第i個地道,q代表查詢包含第i個地道的最大連...