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

来源:互联网 发布:软件封装 可视化代码 编辑:程序博客网 时间:2024/05/17 22:07

题目链接: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---STUDYvoid 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---NSint 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;}


0 0
原创粉丝点击