约会安排---hdu4553(线段树,麻烦的区间覆盖)

时间:2023-03-09 08:33:26
约会安排---hdu4553(线段树,麻烦的区间覆盖)
算是poj3667的加强版,建立两颗线段树,一个是DS区间,另一个是NS区间。那么根据题意,如果是DS的请求,那么首先查找DS的区间,如果有满足的区间就更新DS区间,NS的区间不需要更新。如果是NS的请求,首先看DS区间是否有满足的区间,否则查找NS区间,如果有就同时更新DS区间和NS区间。那么可以归纳为,只要是NS的请求,就同时更新两颗线段树,否则只更新DS的线段树。
注意输出要从Output中复制,不然会wa道底,还有就是Up函数中的if顺序不能变;
这两道题写了一天,不过值了,当然如果不是因为有学长的博客在,我一天根本写不出来,学长毕竟是学长;
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; #define INF 0xfffffff
#define N 110050
#define Lson r<<1
#define Rson r<<1|1 struct SegmentTree
{
int L, R;
bool ns, ds, study; ///0代表
int lsum[], rsum[], sum[]; ///0是屌丝,1女神; ///lsum区间左边(从L开始)连续最大不被覆盖的值
///rsum区间右边(到R介绍)连续最大不被覆盖的值
///sum整个区间连续最大不被覆盖的值 int Mid() { return (L+R)>>;}
int len() { return R-L+; } void clearPlan(bool x)///清空;
{
if(x)
{
lsum[] = lsum[] = len();
rsum[] = rsum[] = len();
sum[] = sum[] = len();
ns = ds = false; study = true;
}
} void NS(bool x)///女神;
{
if(x)
{
lsum[] = lsum[] = ;
rsum[] = rsum[] = ;
sum[] = sum[] = ;
ns = true; ds = false;
}
}
void DS(bool x)///屌丝;
{
if(x)
{
lsum[] = rsum[] = sum[] = ;
ds = true;
}
}
} a[N<<]; void Build(int r, int L, int R)
{
a[r].L = L, a[r].R = R;
a[r].clearPlan(true);///清空 ;
a[r].ns = a[r].ds = a[r].study = false; if(L == R)return ; Build(Lson, L, a[r].Mid());
Build(Rson, a[r].Mid()+, R);
} void Up(int r, int who)
{
if(a[r].L != a[r].R)
{
a[r].lsum[who] = a[Lson].lsum[who];
a[r].rsum[who] = a[Rson].rsum[who]; if(a[Lson].lsum[who] == a[Lson].len())
a[r].lsum[who] += a[Rson].lsum[who];
if(a[Rson].rsum[who] == a[Rson].len())
a[r].rsum[who] += a[Lson].rsum[who]; a[r].sum[who] = max(a[Lson].rsum[who] + a[Rson].lsum[who],
max(a[Lson].sum[who], a[Rson].sum[who]));
}
} void Down(int r)///这个顺序不能反
{
if(a[r].study)
{
a[Lson].clearPlan(true);
a[Rson].clearPlan(true);
a[r].study = false;
}
if(a[r].ns)
{
a[Lson].NS(true);
a[Rson].NS(true);
a[r].ns = a[r].ds = false;
}
if(a[r].ds)
{
a[Lson].DS(true);
a[Rson].DS(true);
a[r].ds = false;
}
} void Update(int r, int L, int R, int flag)
{
if(a[r].L == L && a[r].R == R)
{
if(flag == ) a[r].DS(true);
if(flag == ) a[r].NS(true);
if(flag == ) a[r].clearPlan(true); return;
} Down(r); if( R <= a[r].Mid())
Update(Lson, L, R, flag);
else if( L > a[r].Mid())
Update(Rson, L, R, flag);
else
{
Update(Lson, L, a[r].Mid(), flag);
Update(Rson, a[r].Mid()+, R, flag);
}
Up(r, );
Up(r, );
} int Query(int r, int num, int who)
{
Down(r); if(a[r].sum[who] < num) return ; if(a[r].lsum[who] >= num) return a[r].L;
if(a[Lson].sum[who] >= num) return Query(Lson, num, who); if(a[Lson].rsum[who]+a[Rson].lsum[who] >= num)
return a[Lson].R - a[Lson].rsum[who] + ;
return Query(Rson, num, who);
} int main()
{
int n, m, T, t = , R, L, time; scanf("%d", &T);
while(T--)
{
scanf("%d %d", &n, &m);
Build(, , n); printf("Case %d:\n", t++);
while(m--)
{
char s[];
scanf("%s", s);
if(s[] == 'D')
{
scanf("%d", &time);
L = Query(, time, );///屌丝是0; if( !L )printf("fly with yourself\n");
else
{
Update(, L, L+time-, );
printf("%d,let's fly\n", L);
}
}
else if(s[] == 'N')
{
scanf("%d", &time); L = Query(, time, );///先在屌丝时间里找;当在屌丝时间里没时间时在女神时间里找;
if( !L ) L = Query(, time, );///女神是1; if( !L )printf("wait for me\n");
else
{
Update(, L, L+time-, );
printf("%d,don't put my gezi\n", L);
}
}
else
{
scanf("%d %d", &L, &R);
Update(, L, R, );
printf("I am the hope of chinese chengxuyuan!!\n");
}
}
}
return ;
}