码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-04-29 01:34:40      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

 
算是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[2], rsum[2], sum[2];  ///0是屌丝,1女神;

    ///lsum区间左边(从L开始)连续最大不被覆盖的值
    ///rsum区间右边(到R介绍)连续最大不被覆盖的值
    ///sum整个区间连续最大不被覆盖的值

    int Mid() { return (L+R)>>1;}
    int len() { return R-L+1; }

    void clearPlan(bool x)///清空;
    {
        if(x)
        {
            lsum[0] = lsum[1] = len();
            rsum[0] = rsum[1] = len();
            sum[0] = sum[1] = len();
            ns = ds = false; study = true;
        }
    }

    void NS(bool x)///女神;
    {
        if(x)
        {
            lsum[0] = lsum[1] = 0;
            rsum[0] = rsum[1] = 0;
            sum[0] = sum[1] = 0;
            ns = true; ds = false;
        }
    }
    void DS(bool x)///屌丝;
    {
        if(x)
        {
            lsum[0] = rsum[0] = sum[0] = 0;
            ds = true;
        }
    }
} a[N<<2];

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()+1, 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 == 3) a[r].DS(true);
        if(flag == 2) a[r].NS(true);
        if(flag == 1) 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()+1, R, flag);
    }
    Up(r, 0);
    Up(r, 1);
}

int Query(int r, int num, int who)
{
    Down(r);

    if(a[r].sum[who] < num) return 0;

    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] + 1;
    return Query(Rson, num, who);
}

int main()
{
    int n, m, T, t = 1, R, L, time;

    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d", &n, &m);
        Build(1, 1, n);

        printf("Case %d:\n", t++);
        while(m--)
        {
            char s[1100];
            scanf("%s", s);
            if(s[0] == D)
            {
                scanf("%d", &time);
                L = Query(1, time, 0);///屌丝是0;

                if( !L )printf("fly with yourself\n");
                else
                {
                    Update(1, L, L+time-1, 3);
                    printf("%d,let‘s fly\n", L);
                }
            }
            else if(s[0] == N)
            {
                scanf("%d", &time);

                L = Query(1, time, 0);///先在屌丝时间里找;当在屌丝时间里没时间时在女神时间里找;
                if( !L ) L = Query(1, time, 1);///女神是1;

                if( !L )printf("wait for me\n");
                else
                {
                    Update(1, L, L+time-1, 2);
                    printf("%d,don‘t put my gezi\n", L);
                }
            }
            else
            {
                scanf("%d %d", &L, &R);
                Update(1, L, R, 1);
                printf("I am the hope of chinese chengxuyuan!!\n");
            }
        }
    }
    return 0;
}
View Code

 

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

标签:

原文地址:http://www.cnblogs.com/zhengguiping--9876/p/5444930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!