HDU 4553 约会安排 [线段树]
http://acm.hdu.edu.cn/showproblem.php?pid=4553
题意:有个屌丝有T的空闲时间。每次有人与他约t的时间,他都会找到最靠前的一段符合要求的时间,称为“最先适应算法”。
1,如果基友约他,他就会按“最先适应算法”去找,找到就约否则不约。
2,如果女神约他,他也会先按原先的方法去找,如果找不到,那他会忽略所有与基友的约定而通过原来的方法去找跟女神约会的时间,找到就约否则不约。
3,有时他会脑抽,选择一个区间
思路:
可以用两棵线段树去维护这段时间,一棵维护全部的安排,一棵只维护和女神的安排。若基友来约,则直接从全部安排中找时间,若女神来约,则先从全部的找,找不到再从另一棵中找(相当于忽略了基友)。
接下来说怎么找空闲时间:
用1表示空闲0表示有安排。
用
对于询问
若
若
若
若
否则 向右子树递归,返回其结果。
#include<iostream>
#include<cstdio>
#include<cstring>
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{
int maxlen[maxn];
int left[maxn], middle[maxn], right[maxn];
int setv[maxn];
void init(){
setv[1] = 1;
}
void maintain(int node,int L,int R){
if(setv[node] >= 0){
maxlen[node] = left[node] = right[node] = middle[node] =
(setv[node] ? (R-L+1) : 0);
} else {
CHD;MID;
left[node] = left[lc];
if(left[lc]==(mid-L+1)) left[node] += left[rc];
middle[node] = right[lc]+left[rc];
right[node] = right[rc];
if(right[rc]==R-mid) right[node] += right[lc];
maxlen[node] = max(max(maxlen[lc],maxlen[rc]),middle[node]);
}
}
void pushDown(int node){
if(setv[node] >= 0){
CHD;
setv[lc] = setv[rc] = setv[node];
setv[node] = -1;
}
}
int query(int val,int node,int L,int R){
maintain(node,L,R);
if(val > maxlen[node])return 0; //不在此结点上
if(left[node] >= val)return L; //left
MID;CHD;
pushDown(node);
maintain(rc,mid+1,R); //先维护好右结点信息,方便直接返回
int tmp;
if((tmp=query(val,lc,L,mid))) return tmp; //leftmax
if(middle[node] >= val) return mid-right[lc]+1; //middle
return query(val,rc,mid+1,R); //肯定在右结点上
}
void update(int from,int to,int val,int node,int L,int R){
if(from <= L && R <= to){
setv[node] = val;
}else{
pushDown(node);
MID;CHD;
if(from <= mid) update(from,to,val,lc,L,mid);
else maintain(lc,L,mid);
if(to > mid) update(from,to,val,rc,mid+1,R);
else maintain(rc,mid+1,R);
}
maintain(node,L,R);
}
}ns,all;
int main(){
int T;
scanf("%d",&T);
rep(cas,1,T){
int n,m;
scanf("%d%d",&n,&m);
ns.init();all.init();
printf("Case %d:\n",cas);
while(m--){
char s[10];int a,b;
int ans;
scanf("%s",s);
switch(s[0]){
case 'N':
scanf("%d",&a);
if((ans=all.query(a,1,1,n))||(ans=ns.query(a,1,1,n))){
all.update(ans,ans+a-1,0,1,1,n);
ns.update(ans,ans+a-1,0,1,1,n);
printf("%d,don\'t put my gezi\n",ans);
} else {
printf("wait for me\n");
}
break;
case 'D':
scanf("%d",&a);
ans = all.query(a,1,1,n);
if(ans){
all.update(ans,ans+a-1,0,1,1,n);
printf("%d,let\'s fly\n",ans);
}else{
printf("fly with yourself\n");
}
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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。