題意:有個屌絲有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中更新 題目的難點是如何找合適的連續區間。因為題目要求的是最左邊的符合題目要求的區間,所以找區間的時候要先看左區間的連續長度,其次是中間區間的連續長度 因為中間可能會有多個連續的區間...