描述
1~n區間初始全部為1,每次申請一段長為x的連續區間,返回最靠左的起點位置。此題要求維護兩個樹的最大連續欄位和。
分析記錄此題主要還是因為這個區間合併於自己之前寫的方式不太一樣,查詢時先看左子樹內是否存在,這樣的區間,再去看中間,中間滿足就直接返回,最後看右子樹。遞迴結束條件就是當前節點的左端最長大於等於請求的長度。
**
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define cl (k<<1)
#define cr (k<<1|1)
#define mid ((a[k].l+a[k].r)>>1)
#define mem(a,x) memset(a,x,sizeof(a))
using
namespace std;
#define bug printf("???\n")
typedef
long
long ll;
const
int inf=
0x3f3f3f3f
;const
double eps=
1e-7
;const
int maxn=
100050
;struct naa[maxn*4]
,bb[maxn*4]
;//aa維護**和女神時間 bb維護女神時間
void
up(n&x,n&y,n&z)
void
down
(n *a,
int k)
else
a[k]
.lz =-1
;}void
build
(n *a,
int k,
int l,
int r)
build
(a, cl, l, mid)
;build
(a, cr, mid+
1, r);up
(a[k]
,a[cl]
,a[cr]);
}int
get(n *a,
int k,
int len)
if(a[k]
.lz!=-1
)down
(a,k);if
(a[cl]
.ma>=len)
return
get(a,cl,len);if
(a[cl]
.ra+a[cr]
.la>=len)
//if(a[cr].ma>=len)
return
get(a,cr,len);}
void
clear
(n *a,
int k,
int l,
int r,
int x)
if(a[k]
.lz!=-1
)down
(a, k);if
(l<=mid)
clear
(a, cl,l,r,x);if
(r> mid)
clear
(a, cr,l,r,x);up
(a[k]
,a[cl]
,a[cr]);
}int
main()
}if(s[0]==
'n')
}printf
("%d,don't put my gezi\n"
,tmp)
;clear
(aa,
1, tmp, tmp+x-1,
0);clear
(bb,
1, tmp, tmp+x-1,
0);}
if(s[0]
=='s')}
}}
HDU 4553 約會安排 線段樹區間合併
需要3個標記,分別是左區間連續長度,右區間連續長度,中間區間的最大連續長度 最大可以通過更新回溯的過程中,pushup中更新 題目的難點是如何找合適的連續區間。因為題目要求的是最左邊的符合題目要求的區間,所以找區間的時候要先看左區間的連續長度,其次是中間區間的連續長度 因為中間可能會有多個連續的區間...
HDU 1540 線段樹 區間合併 最大連續區間)
做kuangbin線段樹專題的時候遇到的題目,感覺這是一道非常有趣的題目。線段樹的題目做的比較少,沒有見過這種通過線段樹在區間上做文章的題目,感覺做完這個題目之後加深了對線段樹左右孩子所覆蓋的區間之間的關係的認識。題意 1 n個地道,m個次操作,d代表摧毀第i個地道,q代表查詢包含第i個地道的最大連...
hdu 1540 線段樹 最大連續區間
在區間中,有三種操作,q x 查詢包含x的最長連續區間 d x 將x點毀掉即x點左右不再連續 r 修復上一次毀壞的點 思路 記錄每個區間的左右端的連續區間長度,x若在左端點連續區間,則該區間只可能是其父親的右孩子,因為如果是左孩子,則訪問其父區間的時候,父區間的左連續區間便已包含x。所以直接將該右孩...