傳送門::
題意:有n個連在一起的地道,接下來m個操作,d x 代表摧毀 x 地道;r 代表修建最近一次摧毀的地道;r x 查詢與x地道相連的地道有多少個(最大連續區間長度)
思路::線段樹
線段樹區間合併問題,維護三個變數
llen ::從左端點開始的最大連續區間長度
rlen::從右端點開始的最大連續區間長度
mlen::該區間的最大連續長度
如何維護呢?
雙親的llen 如果它左孩子的整個區間連續,llen=左孩子llen+右孩子的llen
雙親的rlen 如何它右孩子的整個區間來連續,rlen=右孩子rlen+左孩子的rlen
雙親的mlen 左孩子的mlen,右孩子的mlen,左孩子的rlen+右孩子的llen 三者最大值
至於查詢的話也比較簡單
如果它在左孩子rlen中,結果就是左孩子derlen+右孩子的llen,反之就在左孩子裡
如果他在右孩子的llen中,結果就是右孩子的llen+左孩子的rllen反之就在右孩子裡
1 #include2#define ll long long
3using
namespace
std;
4const
int maxn=5e4+5;5
6int llen[maxn<<2],rlen[maxn<<2],mlen[maxn<<2];7
8 stacks;910
void pushup(int rt,int
m)11
20void build(int l,int r,int
rt)21
24int mid=(l+r)>>1
;25 build(l,mid,2*rt);
26 build(mid+1,r,2*rt+1
);27}28
void update(int l,int r,int rt,int pos,int
k)29
34int mid=(l+r)>>1;35
if(pos<=mid)
36 update(l,mid,2*rt,pos,k);
37else
38 update(mid+1,r,2*rt+1
,pos,k);
39 pushup(rt,r-l+1
);40}41
int query(int l,int r,int rt,int
pos)
4246
int mid=(l+r)>>1;47
if(pos<=mid)
53else59}
60int
main()
6173
else
if(op=='d'
)78else82}
83}84return0;
85 }
線段樹 區間合併 HDU 1540
題意 題意 d 破壞村莊,r 修復最後乙個破損的村莊,q 查詢x在內的連續區間值有多少 思路 建立線段樹,維護左右區間值。注意維護變數為 從左編開始最大連續值,從右邊開始最大值,最大連續值 為了維護最後乙個被破壞的。需要時刻記錄,並且不能只單純記錄乙個,而是需要記錄順序。滿足先入後出的棧操作,傳參即...
線段樹(區間合併)HDU 1540
題意 輸入n,m,給定n個相互連通的村莊,有m個操作,d x,表示破壞x村莊使其與相鄰的兩個村莊不相通,r 表示修復上乙個被破壞的村莊,與相鄰的兩個村莊聯通。q x表示與x相連的村莊有多少個。思路 一開始只知道是線段樹,想著肯定得用結構體記錄每個點的資訊,怎麼記錄就不知道了。然後學了線段樹區間合併。...
HDU 1540 線段樹左右區間合併
題目大概的意思就是求當前這個村莊,左右連續的村莊共有幾個,包括自己。思路 比較容易想到的就是把用線段樹劃分的每乙個區間的左右連續區間長度記錄下來,然後嘗試著吧x這個村莊的左右連續並且沒被摧毀的村莊個數連起來,就能得出答案了。具體看 的注釋 include include include includ...