您的位置:首页 > 运维架构

HDU-4553-约会安排(线段树维护最长连续区间)

2017-02-02 17:08 399 查看
题目链接:HDU-4553-约会安排

线段树维护最长连续区间,query用来找长度=dur的区间左端点,update更新区间内的ll,rr,mm,ill,irr,imm的值 。

#include<bits\stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1e5+7;
int ll[maxn<<2],rr[maxn<<2],mm[maxn<<2];
int ill[maxn<<2],irr[maxn<<2],imm[maxn<<2];

void build(int rt,int l,int r)
{
ll[rt]=rr[rt]=mm[rt]=r-l+1;
ill[rt]=irr[rt]=imm[rt]=r-l+1;
if(l==r) return ;
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
}

void push_up(int rt,int l,int r)
{
int mid=(r+l)>>1;
mm[rt]=max(mm[rt<<1],mm[rt<<1|1]);
mm[rt]=max(mm[rt],rr[rt<<1]+ll[rt<<1|1]);
ll[rt]=ll[rt<<1];
rr[rt]=rr[rt<<1|1];
if(ll[rt]==mid-l+1) ll[rt]+=ll[rt<<1|1];
if(rr[rt]==r-mid) rr[rt]+=rr[rt<<1];

imm[rt]=max(imm[rt<<1],imm[rt<<1|1]);
imm[rt]=max(imm[rt],irr[rt<<1]+ill[rt<<1|1]);
ill[rt]=ill[rt<<1];
irr[rt]=irr[rt<<1|1];
if(ill[rt]==mid-l+1) ill[rt]+=ill[rt<<1|1];
if(irr[rt]==r-mid) irr[rt]+=irr[rt<<1];
}

void push_down(int rt,int l,int r)
{
int mid=(l+r)>>1;
if(mm[rt]==r-l+1)
{
ll[rt<<1]=rr[rt<<1]=mm[rt<<1]=mid-l+1;
ll[rt<<1|1]=rr[rt<<1|1]=mm[rt<<1|1]=r-mid;
}
else if(mm[rt]==0)
{
ll[rt<<1]=rr[rt<<1]=mm[rt<<1]=0;
ll[rt<<1|1]=rr[rt<<1|1]=mm[rt<<1|1]=0;
}
if(imm[rt]==r-l+1)
{
ill[rt<<1]=irr[rt<<1]=imm[rt<<1]=mid-l+1;
ill[rt<<1|1]=irr[rt<<1|1]=imm[rt<<1|1]=r-mid;
}
else if(imm[rt]==0)
{
ill[rt<<1]=irr[rt<<1]=imm[rt<<1]=0;
ill[rt<<1|1]=irr[rt<<1|1]=imm[rt<<1|1]=0;
}
}

// 0---DS 1---NS 2---STUDY
void update(int rt,int l,int r,int ul,int ur,int flag)
{
if(ul<=l&&ur>=r)
{
if(flag==1)
ll[rt]=rr[rt]=mm[rt]=ill[rt]=irr[rt]=imm[rt]=0;
else if(flag==0)
ll[rt]=rr[rt]=mm[rt]=0;
else
ll[rt]=rr[rt]=mm[rt]=ill[rt]=irr[rt]=imm[rt]=r-l+1;
return ;
}
push_down(rt,l,r);
int mid=(l+r)>>1;
if(ul<=mid) update(rt<<1,l,mid,ul,ur,flag);
if(ur>mid) update(rt<<1|1,mid+1,r,ul,ur,flag);
push_up(rt,l,r);
}

// find the left end of a corresponding interval
// 0---DS 1---NS
int query(int rt,int l,int r,int dur,int flag)
{
if(l==r) return l;
int mid=(l+r)>>1;
push_down(rt,l,r);
if(flag)
{
if(imm[rt<<1]>=dur) return query(rt<<1,l,mid,dur,flag);
else if(irr[rt<<1]+ill[rt<<1|1]>=dur) return mid-irr[rt<<1]+1;
else return query(rt<<1|1,mid+1,r,dur,flag);
}
else
{
if(mm[rt<<1]>=dur) return query(rt<<1,l,mid,dur,flag);
else if(rr[rt<<1]+ll[rt<<1|1]>=dur) return mid-rr[rt<<1]+1;
else return query(rt<<1|1,mid+1,r,dur,flag);
}
}
char option[10];
int main()
{
/************
freopen("in.txt","r",stdin);
freopen("out1.txt","w",stdout);
/********************/
int T,kase=0;
int t,n,dur;
scanf("%d",&T);
while(++kase<=T)
{
scanf("%d%d",&t,&n);
printf("Case %d:\n",kase);
build(1,1,t);
for(int i=0;i<n;i++)
{
scanf("%s",option);
if(option[0]=='D')
{
scanf("%d",&dur);
if(mm[1]<dur) puts("fly with yourself");
else
{
int res=query(1,1,t,dur,0);
printf("%d,let's fly\n",res);
update(1,1,t,res,res+dur-1,0);
}
}
else if(option[0]=='N')
{
scanf("%d",&dur);
if(mm[1]>=dur)
{
int res=query(1,1,t,dur,0);
printf("%d,don't put my gezi\n",res);
update(1,1,t,res,res+dur-1,1);
}
else if(imm[1]>=dur)
{
int res=query(1,1,t,dur,1);
printf("%d,don't put my gezi\n",res);
update(1,1,t,res,res+dur-1,1);
}
else
puts("wait for me");
}
else
{
int l,r;
scanf("%d%d",&l,&r);
update(1,1,t,l,r,2);
puts("I am the hope of chinese chengxuyuan!!");
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: