hdu-4533-约会安排

区间合并求值问题。

对于ds,ns分别记录每一个区间的最左长度,最右长度,最长长度。

然后就进行一系列区间合并操作就好了。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define maxn 110000
#define mem(a,b) (memset(a),b,sizeof(a))
#define lmin 1
#define rmax n
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define root lmin,rmax,1
#define now l,r,rt
#define int_now int l,int r,int rt
#define INF 99999999
#define LL long long
#define mod 10007
int dslmost[maxn*4],dsrmost[maxn*4],dsmost[maxn*4];
int nslmost[maxn*4],nsrmost[maxn*4],nsmost[maxn*4];
int push_up(int_now)
{
    int ll=(r+l)/2-l+1;
    int rr=r-l+1-ll;
    dsmost[rt]=dsrmost[rt<<1]+dslmost[rt<<1|1];
    if(dslmost[rt<<1]==ll)dslmost[rt]=ll+dslmost[rt<<1|1];
    else dslmost[rt]=dslmost[rt<<1];
    if(dsrmost[rt<<1|1]==rr)dsrmost[rt]=rr+dsrmost[rt<<1];
    else dsrmost[rt]=dsrmost[rt<<1|1];
    dsmost[rt]=max(dsmost[rt],max(dsmost[rt<<1],dsmost[rt<<1|1]));

    nsmost[rt]=nsrmost[rt<<1]+nslmost[rt<<1|1];
    if(nslmost[rt<<1]==ll)nslmost[rt]=ll+nslmost[rt<<1|1];
    else nslmost[rt]=nslmost[rt<<1];
    if(nsrmost[rt<<1|1]==rr)nsrmost[rt]=rr+nsrmost[rt<<1];
    else nsrmost[rt]=nsrmost[rt<<1|1];
    nsmost[rt]=max(nsmost[rt],max(nsmost[rt<<1],nsmost[rt<<1|1]));
}
int push_down(int_now)
{
    int ll=(r+l)/2-l+1;
    int rr=r-l+1-ll;
    if(dsmost[rt]==r-l+1)
    {
        dsmost[rt<<1]=dslmost[rt<<1]=dsrmost[rt<<1]=ll;
        dslmost[rt<<1|1]=dsmost[rt<<1|1]=dsrmost[rt<<1|1]=rr;

    }
    else if(dsmost[rt]==0)
    {
        dsmost[rt<<1]=dsmost[rt<<1|1]=0;
        dslmost[rt<<1]=dslmost[rt<<1|1]=0;
        dsrmost[rt<<1]=dsrmost[rt<<1|1]=0;
    }


    if(nsmost[rt]==r-l+1)
    {
        nsmost[rt<<1]=nslmost[rt<<1]=nsrmost[rt<<1]=ll;
        nslmost[rt<<1|1]=nsmost[rt<<1|1]=nsrmost[rt<<1|1]=rr;

    }
    else if(nsmost[rt]==0)
    {
        nsmost[rt<<1]=nsmost[rt<<1|1]=0;
        nslmost[rt<<1]=nslmost[rt<<1|1]=0;
        nsrmost[rt<<1]=nsrmost[rt<<1|1]=0;
    }
}
void creat(int_now)
{
    dsmost[rt]=nsmost[rt]=r-l+1;
    dslmost[rt]=nslmost[rt]=r-l+1;
    dsrmost[rt]=nsrmost[rt]=r-l+1;
    if(l!=r)
    {
        creat(lson);
        creat(rson);
    }
}
void updatads(int ll,int rr,int x,int_now)
{
    if(ll>r||rr<l)return;
    if(ll<=l&&rr>=r)
    {
        if(x==0)
            dsmost[rt]=dslmost[rt]=dsrmost[rt]=r-l+1;
        else
            dsmost[rt]=dslmost[rt]=dsrmost[rt]=0;
        return;
    }
    push_down(now);
    updatads(ll,rr,x,lson);
    updatads(ll,rr,x,rson);
    push_up(now);
}
void updatans(int ll,int rr,int x,int_now)
{
    if(ll>r||rr<l)return;
    if(ll<=l&&rr>=r)
    {
        if(x==0)
            nsmost[rt]=nslmost[rt]=nsrmost[rt]=r-l+1;
        else
            nsmost[rt]=nslmost[rt]=nsrmost[rt]=0;
        return;
    }
    push_down(now);
    updatans(ll,rr,x,lson);
    updatans(ll,rr,x,rson);
    push_up(now);
}
int queryds(int x,int_now)
{
    if(dslmost[rt]>=x)return l;
    if(dsmost[rt<<1]>=x)return queryds(x,lson);
    if(dsrmost[rt<<1]+dslmost[rt<<1|1]>=x)return (r+l)/2-dsrmost[rt<<1]+1;
    return queryds(x,rson);
}
int queryns(int x,int_now)
{
    if(nslmost[rt]>=x)return l;
    if(nsmost[rt<<1]>=x)return queryns(x,lson);
    if(nsrmost[rt<<1]+nslmost[rt<<1|1]>=x)return (r+l)/2-nsrmost[rt<<1]+1;
    return queryns(x,rson);
}
int main()
{
    int T,cas;
    scanf("%d",&T);
    cas=0;
    int n,m;
    while(T--)
    {
        cas++;
        scanf("%d%d",&n,&m);
        printf("Case %d:\n",cas);
        creat(root);
        char str[100];
        int t,l,r;
        while(m--)
        {
            scanf("%s",str);
            if(str[0]=='D')
            {
                scanf("%d",&t);
                if(dsmost[1]>=t)
                {
                    int x=queryds(t,root);
                    printf("%d,let's fly\n",x);
                    updatads(x,x+t-1,1,root);
                }
                else printf("fly with yourself\n");
            }
            if(str[0]=='N')
            {
                scanf("%d",&t);
                int x=-1;
                if(dsmost[1]>=t)x=queryds(t,root);
                else if(nsmost[1]>=t)x=queryns(t,root);
                if(x!=-1)
                {
                    printf("%d,don't put my gezi\n",x);
                    updatads(x,x+t-1,1,root);
                    updatans(x,x+t-1,1,root);
                }
                else puts("wait for me");
            }
            if(str[0]=='S')
            {
                scanf("%d%d",&l,&r);
                puts("I am the hope of chinese chengxuyuan!!");
                updatads(l,r,0,root);
                updatans(l,r,0,root);
            }
        }
    }
    return 0;
}











  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值