某一天馬學長給我看了乙個lca的題目,然而確實是lca+樹上差分,但是僅僅有lca和樹上差分解決不了,然後我就去面向題解程式設計了。
可是這個線段樹合併是個什麼東東。。。
然而今天看書,突然看到了這個線段樹合併。
就寫一下了。
%mmh。
p4556 [vani有約會]雨天的尾巴:
題目背景
深繪里一直很討厭雨天。
灼熱的天氣穿透了前半個夏天,後來一場大雨和隨之而來的洪水,澆滅了一切。
雖然深繪里家鄉的小村落對洪水有著頑固的抵抗力,但也倒了幾座老房子,幾棵老樹被連根拔起,以及田地裡的糧食被弄得一片狼藉。
無奈的深繪里和村民們只好等待救濟糧來維生。
不過救濟糧的發放方式很特別。
題目描述
首先村落裡的一共有n座房屋,並形成乙個樹狀結構。然後救濟糧分m次發放,每次選擇兩個房屋(x,y),然後對於x到y的路徑上(含x和y)每座房子裡發放一袋z型別的救濟糧。
然後深繪里想知道,當所有的救濟糧發放完畢後,每座房子裡存放的最多的是哪種救濟糧。
輸入格式
第一行兩個正整數n,m,含義如題目所示。
接下來n-1行,每行兩個數(a,b),表示(a,b)間有一條邊。
再接下來m行,每行三個數(x,y,z),含義如題目所示。
輸出格式
n行,第i行乙個整數,表示第i座房屋裡存放的最多的是哪種救濟糧,如果有多種救濟糧存放次數一樣,輸出編號最小的。
如果某座房屋裡沒有救濟糧,則對應一行輸出0。
輸入輸出樣例
輸入 #1 複製
5 31 2
3 13 4
5 32 3 3
1 5 2
3 3 3
輸出 #1 複製23
302說明/提示
對於20%的資料,1 <= n, m <= 100
對於50%的資料,1 <= n, m <= 2000
對於100%的資料,1 <= n, m <= 100000, 1 <= a, b, x, y <= n, 1 <= z <= 100000
vani
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define llu unsigned ll
using
namespace std;
const
int mod=
1e9+7;
const
int inf=
0x3f3f3f3f
;const ll lnf=
0x3f3f3f3f3f3f3f3f
;const
int maxn=
100100
;struct node
t[maxn*20*
4];int f[maxn][20
],root[maxn]
,d[maxn]
,ans[maxn]
;int head[maxn]
,ver[maxn*2]
,nt[maxn*2]
;int xx[maxn]
,yy[maxn]
,zz[maxn]
,b[maxn]
;int tot=
1,n,m,tt,cnt=
0,pm;
void
add(
int x,
int y)
void
bfs(
void)}
}int
lca(
int x,
int y)
intbuild
(void
)void
pushup
(int p)
void
_insert
(int p,
int l,
int r,
int pos,
int val)
int mid=
(l+r)
>>1;
if(pos<=mid)
else
pushup
(p);
}int
_merge
(int p,
int q,
int l,
int r)
int mid=
(l+r)
>>1;
t[p]
.lc=
_merge
(t[p]
.lc,t[q]
.lc,l,mid)
; t[p]
.rc=
_merge
(t[p]
.rc,t[q]
.rc,mid+
1,r)
;pushup
(p);
return p;
}void
dfs(
int x,
int fa)
ans[x]
=t[root[x]
].pos;
}int
main
(void
)for
(int i=
1;i<=m;i++
)scanf
("%d%d%d"
,&xx[i]
,&yy[i]
,&zz[i]
),b[i]
=zz[i]
;bfs()
;sort
(b+1
,b+m+1)
; pm=
unique
(b+1
,b+m+1)
-(b+1)
;for
(int i=
1;i<=n;i++
) root[i]
=build()
;for
(int i=
1;i<=m;i++
) zz[i]
=lower_bound
(b+1
,b+pm+
1,zz[i]
)-b;
for(
int i=
1;i<=m;i++
)dfs(1
,0);
for(
int i=
1;i<=n;i++
)printf
("%d\n"
,b[ans[i]])
;return0;
}
線段樹合併
做永無鄉的時候,以為是主席樹合併,後來感覺不對勁,唔。x和y是兩顆樹的根。這個演算法是從歸併演算法那引申的。實際運作的時候,考慮到了線段樹的本質 線段樹有效節點就是葉子節點。好像是句廢話。其實不是,這句話啟發我們並不需要合併一整棵樹,我們只需要處理好葉子節點,考慮把y樹合併到x上,那麼把y樹的葉子節...
線段樹合併
今天寫dsu on tree 的時候發現不會寫線段樹合併,於是滾來寫線段樹合併部落格 對於值域相同的兩個權值線段樹x xx和y yy 假設把y yy合併到x xx上 每個節點有兩種情況 其中至少有乙個節點沒有權值 x y x y x y 直接x x y x x y x x y x 0?y x x 0...
線段樹合併
線段樹合併雖說是比較基礎的內容,且我一直都知道大概的實現方式,但直到最近我才正式去寫過一次,我真的太弱了啊。下面從暴力合併開始,依次介紹幾種線段樹合併的方式。直接暴力摳出線段樹中的元素,然後暴力合併。總合併時間複雜度應為 o n 2logn 應該算是暴力合併的一種優化。即,每次合併時選取較小的一棵線...