zoukankan      html  css  js  c++  java
  • 约会安排---hdu4553(线段树,麻烦的区间覆盖)

     
    算是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:
    ", 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
    ");
                    else
                    {
                        Update(1, L, L+time-1, 3);
                        printf("%d,let's fly
    ", 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
    ");
                    else
                    {
                        Update(1, L, L+time-1, 2);
                        printf("%d,don't put my gezi
    ", L);
                    }
                }
                else
                {
                    scanf("%d %d", &L, &R);
                    Update(1, L, R, 1);
                    printf("I am the hope of chinese chengxuyuan!!
    ");
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    面试题 01.04. 回文排列
    面试题 01.03. URL化
    面试题 01.02. 判定是否互为字符重排
    面试题 01.01. 判定字符是否唯一
    剑指 Offer 68
    剑指 Offer 68
    Wpf杀死所有线程、Wpf关闭程序杀死所有线程
    wpf的webbrowser与javascript交互
    WPF将HHMMSS转换为时间格式字符串
    IDEA建立Spring MVC Hello World 详细入门教程
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5444930.html
Copyright © 2011-2022 走看看