hdu 4553 约会安排 (两个线段树维护区间)

Posted xxrlz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 4553 约会安排 (两个线段树维护区间)相关的知识,希望对你有一定的参考价值。

include

include

include

include

include

include

include

include

define ll long long

define FOR(i,l,r) for(int i = l ; i <= r ;++i )

define inf 1<<30

define EPS (1e-9)

define lson(p) (p<<1)

define rson(p) (p<<1|1)

using namespace std;
typedef pair<int,int> pii;
const int N = 1e5+30;
int n,m;
struct node
int l,r;
int lsum,rsum,ssum;
a[N<<2],b[N<<2];

void push_up(int rt,int l,int r)
int mid = (l+r)>>1;
a[rt].lsum = a[lson(rt)].lsum; // 左子树的左连续空间更新父亲
a[rt].rsum = a[rson(rt)].rsum; // 右子树的右连续空间更新父亲
// 总连续空间为 max(左子树总连续,右子树总连续, 左子树右连续+右子树左连续)
a[rt].ssum = max(max(a[lson(rt)].ssum,a[rson(rt)].ssum),a[lson(rt)].rsum+a[rson(rt)].lsum);
if(a[lson(rt)].lsum == mid-l+1) a[rt].lsum += a[rson(rt)].lsum; // 左子树左连续包含了整个左子树,则父亲的左连续扩充右子树的左连续
if(a[rson(rt)].rsum == r-mid) a[rt].rsum += a[lson(rt)].rsum;
b[rt].lsum = b[lson(rt)].lsum;
b[rt].rsum = b[rson(rt)].rsum;
b[rt].ssum = max(max(b[lson(rt)].ssum,b[rson(rt)].ssum),b[lson(rt)].rsum+b[rson(rt)].lsum);
if(b[lson(rt)].lsum == mid-l+1) b[rt].lsum += b[rson(rt)].lsum;
if(b[rson(rt)].rsum == r-mid) b[rt].rsum += b[lson(rt)].rsum;

void push_down(int rt,int l,int r)
int mid = (l+r)>>1;
if(a[rt].ssum == r-l+1) // 父亲被覆盖 ,子区间也被覆盖
a[lson(rt)].lsum = a[lson(rt)].rsum = a[lson(rt)].ssum = mid-l+1;
a[rson(rt)].lsum = a[rson(rt)].rsum = a[rson(rt)].ssum = r-mid;
else if(a[rt].ssum == 0) // 父亲被情空,子区间清空
a[lson(rt)].lsum = a[lson(rt)].rsum = a[lson(rt)].ssum = 0;
a[rson(rt)].lsum = a[rson(rt)].rsum = a[rson(rt)].ssum = 0;

if(b[rt].ssum == r-l+1)
b[lson(rt)].lsum = b[lson(rt)].rsum = b[lson(rt)].ssum = mid-l+1;
b[rson(rt)].lsum = b[rson(rt)].rsum = b[rson(rt)].ssum = r-mid;
else if(b[rt].ssum == 0)
b[lson(rt)].lsum = b[lson(rt)].rsum = b[lson(rt)].ssum = 0;
b[rson(rt)].lsum = b[rson(rt)].rsum = b[rson(rt)].ssum = 0;

void build(int r,int le,int re)
a[r].lsum = b[r].lsum = (re-le+1);
a[r].rsum = b[r].rsum = (re-le+1);
a[r].ssum = b[r].ssum = (re-le+1);
a[r].l = le,a[r].r = re;
b[r].l = le,b[r].r = re;
if(le==re) return ;
int mid = (le+re)>>1;
build(lson(r),le,mid);
build(rson(r),mid+1,re);

void update(int op,int l,int r,int rt)
if(a[rt].l>=l && a[rt].r <=r)
if(op==1) // ds更新自己
a[rt].lsum = a[rt].rsum = a[rt].ssum = 0;
else if(op==0) // ns更新两棵树
a[rt].lsum = a[rt].rsum = a[rt].ssum = 0;
b[rt].lsum = b[rt].rsum = b[rt].ssum = 0;
else // 两棵树清空
a[rt].lsum = a[rt].rsum = a[rt].ssum = a[rt].r-a[rt].l +1;
b[rt].lsum = b[rt].rsum = b[rt].ssum = b[rt].r-b[rt].l +1;

return ;

int mid = (a[rt].l + a[rt].r)>>1;
push_down(rt,a[rt].l,a[rt].r); // 下方标记
if(l<=mid) update(op,l,r,lson(rt));
if(r>mid) update(op,l,r,rson(rt));
push_up(rt,a[rt].l,a[rt].r); // 上提标记

int query(int op,int rt,int len)
if(a[rt].l==a[rt].r) return a[rt].l;
push_down(rt,a[rt].l,a[rt].r);
int mid = (a[rt].l + a[rt].r) >> 1;
if(op) // ds
if(a[lson(rt)].ssum>=len)
return query(op,lson(rt),len);
else if(a[lson(rt)].rsum + a[rson(rt)].lsum >=len) // 左子树的右区间加右子树的左区间满足
return mid-a[lson(rt)].rsum +1; // 起点一定在左子树
else
return query(op,rson(rt),len);
else // ns
if(b[lson(rt)].ssum>= len)
return query(op,lson(rt),len);
else if(b[lson(rt)].rsum + b[rson(rt)].lsum >=len)
return mid-b[lson(rt)].rsum +1;
else
return query(op,rson(rt),len);


char op[20];
void solve(int cas)
printf("Case %d:\n",cas);
scanf("%d%d",&n,&m);
build(1,1,n);
int l,r;
FOR(i,1,m)
scanf("%s%d",op,&l);
if(op[0]==‘D‘)
if(a[1].ssum>=l)
int pos = query(1,1,l);
printf("%d,let‘s fly\n",pos);
update(1,pos,pos+l-1,1);
else
puts("fly with yourself");

else if(op[0]==‘N‘)
if(a[1].ssum>=l)
int pos = query(1,1,l);
printf("%d,don‘t put my gezi\n",pos);
update(0,pos,pos+l-1,1);
else if(b[1].ssum>=l)
int pos = query(0,1,l);
printf("%d,don‘t put my gezi\n",pos);
update(0,pos,pos+l-1,1);
else
puts("wait for me");

else
scanf("%d",&r);
update(2,l,r,1);
printf("I am the hope of chinese chengxuyuan!!\n");



int main()
int t;
scanf("%d",&t);
for(int i=1;i<=t;++i)
solve(i);

return 0;

以上是关于hdu 4553 约会安排 (两个线段树维护区间)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4553 约会安排(线段树区间合并+双重标记)

HDU 4553 约会安排 (区间合并)线段树

约会安排 HDU

hdu 4553 约会安排

HDU 4553 约会安排

约会安排 HDU - 4553