title: hdu-1540線段樹刷題
date: 2018-10-18 19:55:21
tags:
哇,,,這道線段樹的題可以說是到目前為止我所做過的最難的一道了吧qaq,,,,,,
一開始讀完題就是一臉懵逼,,,,完全不知道該從**下手,,,就是知道這是一道線段樹的題也不知道該怎麼下手啊啊啊,,,,
最後還是看了kaungbin大佬的**,,,qaq
光是讀**就花了一兩個小時,,,(不過也有可能和今天賊困有關,,,腦袋不怎麼轉啊
大概的題意就是一串在一條線上的村莊,,或者說是點,,,一開始都為1,,,然後有三種不同的操作,,,
一開始我看到有需要上一次操作的情況,,就想著要將這些d操作儲存下來,,適合這道題的就是棧,,,
然後就是詢問了,,,我那時想著既然要求a周圍這些1的個數,,那我就找到兩端的0不就行了,,,然後從這裡就徹底的腦抽了,,,又想著用線段樹去求這段區間的和,,,,然後結果顯而易見,,,,t了,,,
因為,,這種想法線段樹根本沒有用啊!!!!都找出那兩端的0所在的位置直接減不就行了,,,這不就是裸暴力嗎,,,,,哇,,,被自己蠢哭(๐॔˃̶ᗜ˂̶๐॓),,,,
首先將這段線劃分成多個區段,,,每個區段儲存的資訊有:從這去區段的左端點開始最長的連續1的個數ll、從這個區段右端點開始的最長的連續1的個數rl、 還有這個區段最大的連續點的個數ml。。。
建樹:ll = rl = ml = 區間長
更新:
葉子節點置一置零,,,
左右遞迴更新
其他區間:(pushup())父節點.ll = 左節點.ll 父節點.rl = 右節點.rl
父節點.ml取左右節點的最大的乙個ml
若左節點的rl + 右節點的ll > 父節點的ml,,,,就更新為前者
對於父節點的ll,rl查詢:如果左節點的ll為左節點的長度,,,就說明左節點從左端點開始的連續1的最大的個數就為左節點包含的點的個數,,,所以此時的父節點的ll就要和右節點的ll合併
同理,,,父節點的rl也要進行這樣的判斷
對於一些特殊的區間直接返回該區間的最大的連續1的個數也就是ml
當loc在中點左時,,,就要從左節點來判斷,,,判斷的條件是loc是否超出了rl的最左端(畫圖更容易理解一些),,,超出的話就說明loc所在的連續的1一部分是在左節點的rl裡另一部分是在右節點的ll裡,,,就分成兩個點查詢,,,乙個是在左節點的loc,,,另乙個時在右節點的mid+1那個點字醜見諒,,,,(不過應該沒人看把,,,,同理,,若在中點的右時也有類似的判斷,,,
大體上說就是不斷地判斷要找到那個點相對ll,rl的位置,,,最後把遞迴查詢到的結果合併就行了,,,
//遞迴更新
//先更新父節點的兩個,ll,rl
node[rt].ll = node[rt << 1].ll;
node[rt].rl = node[rt << 1 | 1].rl;
//然後是父節點的ml
node[rt].ml = max(node[rt << 1].ml , node[rt << 1 | 1].ml);
node[rt].ml = max(node[rt].ml , node[rt << 1].rl + node[rt << 1 | 1].ll);
//父節點的ll,rl可能就是左右節點的ll,,rl,,,,當剛好是子節點的全部時還要加上另乙個區間的一部分
if(node[rt << 1].ll == node[rt << 1].r - node[rt << 1].l + 1)
node[rt].ll += node[rt << 1 | 1].ll;
if(node[rt << 1 | 1].rl == node[rt << 1 | 1].r - node[rt << 1 | 1].l + 1)
node[rt].rl += node[rt << 1].rl;
return;
}int query(int rt , int loc)
else
}int main()
else if(c == 'q')
else}}
}return 0;
}//kaungbin
線段樹 區間合併 HDU 1540
題意 題意 d 破壞村莊,r 修復最後乙個破損的村莊,q 查詢x在內的連續區間值有多少 思路 建立線段樹,維護左右區間值。注意維護變數為 從左編開始最大連續值,從右邊開始最大值,最大連續值 為了維護最後乙個被破壞的。需要時刻記錄,並且不能只單純記錄乙個,而是需要記錄順序。滿足先入後出的棧操作,傳參即...
HDU 1540 線段樹(區間查詢)
有n個點,每兩個點之間存在一條通路,d x代表摧毀x點,r代表修復最近摧毀的乙個點。q x代表查詢x點能連線多少個村莊 包括自己 比較複雜的線段樹。狀態需要用結構體儲存。l,r代表左邊界和右邊界,ls代表左連續區間長度,rs代表右連續區間長度。ms代表區間內最大連續長度。初始化過程都初始化成1就可以...
線段樹(區間合併)HDU 1540
題意 輸入n,m,給定n個相互連通的村莊,有m個操作,d x,表示破壞x村莊使其與相鄰的兩個村莊不相通,r 表示修復上乙個被破壞的村莊,與相鄰的兩個村莊聯通。q x表示與x相連的村莊有多少個。思路 一開始只知道是線段樹,想著肯定得用結構體記錄每個點的資訊,怎麼記錄就不知道了。然後學了線段樹區間合併。...