M

寒假来了,又到了小明和女神们约会的季节。 
  小明虽为�丝级码农,但非常活跃,女神们常常在小明网上的大段发言后热情回复“呵呵”,所以,小明的最爱就是和女神们约会。与此同时,也有很多基友找他开黑,由于数量实在过于巨大,怎么安排时间便成了小明的一大心事。 
  我们已知小明一共有T的空闲时间,期间会有很多女神或者基友来找小明。 
  作为一个操作系统曾经怒考71分的大神,小明想到了一个算法,即“首次适应算法”,根据操作系统课本的描述,就是找一段最靠前的符合要求的连续空间分配给每个请求,由此小明做出了一个决定: 
  当一个基友来找小明时,小明就根据“首次适应算法”来找一段空闲的时间来和基友约好,如果找到,就说“X,let’s fly”(此处,X为开始时间),否则就说“fly with yourself”; 
  当女神来找小明时,先使用一次“首次适应算法”,如果没有找到,小明就冒着木叽叽的风险无视所有�丝基友的约定,再次使用“无视基友首次适应算法”,两次只要有一次找到,就说“X,don’t put my gezi”(此处,X为开始时间),否则就说“wait for me” 
  当然,我们知道小明不是一个节操负无穷的人,如果和女神约会完,还有剩余时间,他还是会和原来约好的基友去dota的。(举个例子:小西(�丝)和小明约好在1~5这个时间单位段内打dota,这时候,女神来和小明预约长度为3的时间段,那么最终就是1~3小明去和女神约会,搞定后在4~5和小西打dota) 
  小明偶尔也会想要学习新知识,此时小明就会把某一个时间区间的所有已经预定的时间全部清空用来学习并且怒吼“I am the hope of chinese chengxuyuan!!”,不过小明一般都是三分钟热度,再有人来预定的话,小明就会按耐不住寂寞把学习新知识的时间分配出去。
 

Input

输入第一行为CASE,表示有CASE组测试数据; 
每组数据以两个整数T,N开始,T代表总共的时间,N表示预约请求的个数; 
接着的N行,每行表示一个女神或者基友的预约,“NS QT”代表一个女神来找小明约一段长为QT的时间,“DS QT”则代表一个�丝的长为QT的请求,当然也有可能是小明想学知识了,“STUDY!! L R”代表清空L~R区间内的所有请求。 

[Technical Specification] 
1. 1 <= CASE <= 30 
2. 1 <= T, N <= 100000 
3. 1 <= QT <= 110000 
4. 1 <= L <= R <=T
 

Output

对于每一个case,第一行先输出“Case C:”代表是第几个case,然后N行,每行对应一个请求的结果(参照描述)。 
输出样本(可复制此处): 
“X,let's fly”,”fly with yourself”,”X,don't put my gezi”,”wait for me”,”I am the hope of chinese chengxuyuan!!” 
 

Sample Input

1 5 6 DS 3 NS 2 NS 4 STUDY!! 1 5 DS 4 NS 2
 

Sample Output

Case 1: 1,let's fly 4,don't put my gezi wait for me I am the hope of chinese chengxuyuan!! 1,let's fly 1,don't put my gezi
分析:如果做过 poj的3667题会发现这题不难的,只不过是复杂了一点罢了,不过从昨晚下午5点多开始做,到晚上11.40才调处来找到bug,因为实在是找不出来错误最后重新复制的输出,发现就然对了,仔细研究下发现原来是从文章里面复制出来的句子包含中文的标点,标点啊,非常难发现的的东西,尤其是使用cb编译器,几乎没有看出来有什么区别......也是涨了一次教训吧,以后代码的输出要在给的标准输出里面复制,不要再文章里面复制。
*******************************************************************
#include<algorithm>
#include<stdio.h>
#include<stack>
#include<string.h>
using namespace std;

#define lson r<<1
#define rson r<<1|1

const int maxn = 1e5+5;

struct segmentTree
{///bool操作分别代表 女神屌丝,学习
    int L, R, lsum[2], rsum[2], sum[2];///0是屌丝,1是女神
    bool ns, ds, study;

    int mid(){return (L+R)>>1;}
    int len(){return R-L+1;}
    void clearPlan(int fstudy)
    {///准备学习,清空所有计划
        if(fstudy == true)
        {
            lsum[0] = lsum[1] = len();
            rsum[0] = rsum[1] = len();
            sum[0] = sum[1] = len();
            study = true; ds = ns = false;
        }
    }
    void Plmm(int fns)
    {///女生占用时间,屌丝无法占用
        if(fns == true)
        {
            lsum[0] = lsum[1] = 0;
            rsum[0] = rsum[1] = 0;
            sum[0] = sum[1] = 0;
            ns = true, ds = false;
        }
    }
    void DiaoSi(int fds)
    {///屌丝一起打游戏占用时间,可被女神再次占过来
        if(fds == true)
        {
            lsum[0] = rsum[0] = sum[0] = 0;
            ds = true;
        }
    }
}a[maxn<<2];

void Build(int r, int L, int R)
{
    a[r].L = L, a[r].R = R;
    a[r].clearPlan(1);
    a[r].study = a[r].ds = a[r].ns = false;

    if(L == R)return ;

    Build(lson, L, a[r].mid());
    Build(rson, a[r].mid()+1, R);
}
void pushDown(int r)
{
    if( a[r].study )
    {
        a[lson].clearPlan(true);
        a[rson].clearPlan(true);
        a[r].study = false;
    }

    if( a[r].ns )
    {
        a[lson].Plmm(true);
        a[rson].Plmm(true);
        a[r].ns = a[r].ds = false;
    }

    if( a[r].ds )
    {
        a[lson].DiaoSi(true);
        a[rson].DiaoSi(true);
        a[r].ds = false;
    }
}
void pushUp(int r, int k)
{///k等于 0 更新屌丝区间, 等于1更新女神区间
    a[r].lsum[k] = a[lson].lsum[k], a[r].rsum[k] = a[rson].rsum[k];

    if( a[lson].lsum[k] == a[lson].len() )
        a[r].lsum[k] += a[rson].lsum[k];
    if( a[rson].rsum[k] == a[rson].len() )
        a[r].rsum[k] += a[lson].rsum[k];

    a[r].sum[k] = max( a[lson].sum[k], max( a[rson].sum[k], a[lson].rsum[k] + a[rson].lsum[k] ) );
}
///op等于1时学习,2女神,3屌丝
void upDate(int r, int L, int R, int op)
{
    if( a[r].L == L && a[r].R == R )
    {
        if(op == 1) a[r].clearPlan(true);
        if(op == 2) a[r].Plmm(true);
        if(op == 3) a[r].DiaoSi(true);

        return ;
    }

    pushDown(r);

    if(R <= a[r].mid())
        upDate(lson, L, R, op);
    else if(L > a[r].mid())
        upDate(rson, L, R, op);
    else
    {
        upDate(lson, L, a[r].mid(), op);
        upDate(rson, a[r].mid()+1, R, op);
    }

    pushUp(r, 0);
    pushUp(r, 1);
}
///查找女神或者屌丝是否有k时间,k等于0屌丝,1女神,有的话返回下标没有返回0
int  Query(int r, int t, int k)
{
    pushDown(r);

    if( a[r].sum[k] < t )return 0;

    if( a[r].lsum[k] >= t)return a[r].L;
    if( a[lson].sum[k] >= t ) return Query(lson, t, k);
    if( a[lson].rsum[k] + a[rson].lsum[k] >= t )
        return a[lson].R - a[lson].rsum[k]  + 1;
    return Query(rson, t, k);
}

int main()
{
    int T, t=1;

    scanf("%d", &T);

    while(T--)
    {
        int N, M, x, y; char s[20];

        scanf("%d%d", &N, &M);

        Build(11, N);

        printf("Case %d: ", t++);

        while(M--)
        {
            scanf("%s%d", s, &x);

            if(s[0] == 'S')
            {
                scanf("%d", &y);
                upDate(1, x, y, 1);
                printf("I am the hope of chinese chengxuyuan!! ");
            }
            else if(s[0] == 'N')
            {
                y = Query(1, x, 0);
                if(!y) y = Query(1, x, 1);

                if(y)
                {
                    upDate(1, y, y+x-12);
                    printf("%d,don't put my gezi ", y);
                }
                else
                    printf("wait for me ");
            }
            else
            {
                y = Query(1, x, 0);

                if(y)
                {
                    upDate(1, y, y+x-13);
                    printf("%d,let's fly ", y);
                }
                else
                    printf("fly with yourself ");
            }
        }
    }

    return 0; 

}

原文地址:https://www.cnblogs.com/liuxin13/p/4684917.html