HDU 4553 約會安排 線段樹

2021-07-02 04:13:33 字數 1832 閱讀 1290

題意:有個屌絲有t的空閒時間。每次有人與他約t的時間,他都會找到最靠前的一段符合要求的時間,稱為「最先適應演算法」。

1,如果**約他,他就會按「最先適應演算法」去找,找到就約否則不約。

2,如果女神約他,他也會先按原先的方法去找,如果找不到,那他會忽略所有與**的約定而通過原來的方法去找跟女神約會的時間,找到就約否則不約。

3,有時他會腦抽,選擇乙個區間 [l

,r] ,將該區間的安排都清空。

思路:

可以用兩棵線段樹去維護這段時間,一棵維護全部的安排,一棵只維護和女神的安排。若**來約,則直接從全部安排中找時間,若女神來約,則先從全部的找,找不到再從另一棵中找(相當於忽略了**)。le

ft[i

] 表示

i 結點對應區間 [l

,r]中左連續最長空閒時間, ri

ght[

i]表示右連續最長空閒時間, mi

ddle

[i] 表示橫跨該結點左右子結點的最長連續空閒時間, ma

xlen

[i] 表示該結點表示區間中的最長空閒時間

對於詢問

t ,按以下順序判斷: 若 m

axle

n[i]

<

t則此結點無解。 若 l

eft[

i]≥t

,則返回

l (空閒時段起點) 若 m

axle

n[lc

]≥t,則向左子樹遞迴,返回其結果。 若 m

iddl

e[i]

≥t,則返回 mi

d−ri

ght[

lc]+

1 ,即跨左右子樹的起點。

否則 向右子樹遞迴,返回其結果。

#include

#include

#include

using

namespace

std;

#define rep(i,f,t) for(int i = (f),_end = (t); i <= _end; ++i)

#define mid int mid = (l+r)>>1;

#define chd int lc = node<<1, rc = node<<1|1;

const

int maxn = 100001

<<2;

struct sgt

void maintain(int node,int l,int r) else

}void pushdown(int node)

}int query(int val,int node,int l,int r)

void update(int from,int to,int val,int node,int l,int r)else

maintain(node,l,r);

}}ns,all;

int main() else

break;

case

'd':

scanf("%d",&a);

ans = all.query(a,1,1,n);

if(ans)else

break;

case

's':

scanf("%d%d",&a,&b);

all.update(a,b,1,1,1,n);

ns.update(a,b,1,1,1,n);

printf("i am the hope of chinese chengxuyuan!!\n");

break;}}

}return

0;}

hdu4553約會安排 線段樹

ds qt 找一段最靠前的長度為qt的空間 ns qt 找一段最靠前的長度為qt的空間,如果沒找到可以將ds佔據的空間當做空閒空間,找一段最靠前的空間 study l r 清空l r的空間 用兩個線段樹,乙個處理ds的情況,乙個處理ns的情況 線段樹維護,ma l ma r ma 區間 l,r 的左...

hdu4553約會安排 線段樹

ds qt 找一段最靠前的長度為qt的空間 ns qt 找一段最靠前的長度為qt的空間。假設沒找到能夠將ds占領的空間當做空暇空間,找一段最靠前的空間 study l r 清空l r的空間 用兩個線段樹,乙個處理ds的情況。乙個處理ns的情況 線段樹維護,ma l ma r ma 區間 l,r 的左...

HDU 4553 約會安排 線段樹區間合併

需要3個標記,分別是左區間連續長度,右區間連續長度,中間區間的最大連續長度 最大可以通過更新回溯的過程中,pushup中更新 題目的難點是如何找合適的連續區間。因為題目要求的是最左邊的符合題目要求的區間,所以找區間的時候要先看左區間的連續長度,其次是中間區間的連續長度 因為中間可能會有多個連續的區間...