<题目链接>

  寒假来了,又到了小明和女神们约会的季节。 
  小明虽为屌丝级码农,但非常活跃,女神们常常在小明网上的大段发言后热情回复“呵呵”,所以,小明的最爱就是和女神们约会。与此同时,也有很多基友找他开黑,由于数量实在过于巨大,怎么安排时间便成了小明的一大心事。 
  我们已知小明一共有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


解题分析:
由于本题要查询连续区间,所以要用到区间合并,每个点维护三个值,该点对应区间的最长连续长度,最长连续前、后缀长度。并且,本题还涉及一个优先级的概念,因此,建立两个线段树,对这两个线段树进行操作,从而达到模拟优先级的作用,具体实现见代码。

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; #define Lson rt<<1,l,mid
#define Rson rt<<1|1,mid+1,r
const int M =1e5+;
int n,q;
int tr[M<<][],llen[M<<][],rlen[M<<][];
int lazy[M<<][]; void Pushup(int rt,int len,int ty){ //区间合并,维护最长连续区间
llen[rt][ty]=llen[rt<<][ty];
rlen[rt][ty]=rlen[rt<<|][ty];
if(llen[rt<<][ty]==(len-(len>>)))llen[rt][ty]+=llen[rt<<|][ty];
if(rlen[rt<<|][ty]==(len>>))rlen[rt][ty]+=rlen[rt<<][ty];
tr[rt][ty]=max(max(tr[rt<<][ty],tr[rt<<|][ty]),rlen[rt<<][ty]+llen[rt<<|][ty]);
}
void Pushdown(int rt,int len,int ty){ //将lazy标记下放
if(lazy[rt][ty]!=-){
int tmp=lazy[rt][ty];
tr[rt<<][ty]=llen[rt<<][ty]=rlen[rt<<][ty]=(len-(len>>))*tmp;
tr[rt<<|][ty]=llen[rt<<|][ty]=rlen[rt<<|][ty]=(len>>)*tmp;
lazy[rt<<][ty]=lazy[rt<<|][ty]=tmp;
lazy[rt][ty]=-;
}
}
void build(int rt,int l,int r,int ty){
lazy[rt][ty]=-;
if(l==r){
tr[rt][ty]=llen[rt][ty]=rlen[rt][ty]=; //值为1代表该点有时间,为0代表没时间
return;
}
int mid=(l+r)>>;
build(Lson,ty);
build(Rson,ty);
Pushup(rt,r-l+,ty);
}
void update(int rt,int l,int r,int L,int R,int c,int ty){
if(L<=l&&r<=R){
lazy[rt][ty]=c;
tr[rt][ty]=llen[rt][ty]=rlen[rt][ty]=(r-l+)*c;
return;
}
Pushdown(rt,r-l+,ty);
int mid=(l+r)>>;
if(L<=mid)update(Lson,L,R,c,ty);
if(R>mid)update(Rson,L,R,c,ty);
Pushup(rt,r-l+,ty);
}
int query(int rt,int l,int r,int len,int ty){ //返回满足连续区间>=len的区间最左值,掌握这种query函数
if(l==r)return l;
Pushdown(rt,r-l+,ty);
int mid=(l+r)>>;
//因为要尽量使符合要求的区间靠前,所以这里按左、中、右的顺序来查询
if(tr[rt<<][ty]>=len)return query(Lson,len,ty);
else if(rlen[rt<<][ty]+llen[rt<<|][ty]>=len)return mid-rlen[rt<<][ty]+; //如果是在左右子区间的后缀、前缀之间,则直接返回左区间的后缀最左值的下标
else return query(Rson,len,ty);
}
int main(){
int T,ncase=;scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&q);
build(,,n,); //基友的请求建一个线段树
build(,,n,); //女神的请求建一颗线段树,更新的时候,根据优先级,对这两个不同的线段树进行操作
char op[];
int x,y;
printf("Case %d:\n", ++ncase);
while(q--){
scanf("%s",op);
if(op[]=='D'){
scanf("%d",&x);
if(tr[][]>=x){ //如果存在>=x的连续区间
int ans=query(,,n,x,); //得到符合要求区间的最左值下标
printf("%d,let's fly\n", ans);
update(,,n,ans,ans+x-,,); //只更新基友树上的时间安排
}
else printf("fly with yourself\n");
}
else if(op[]=='N'){
scanf("%d",&x);
if(tr[][]>=x){ //如果不用占用基友的时间也能与女神约会,即如果优先级低的基友树上也能满足
int ans=query(,,n,x,);
printf("%d,don't put my gezi\n", ans);
update(,,n,ans,ans+x-,,); //基友树上要更新一段
update(,,n,ans,ans+x-,,); //女神树上也要更新同样一段,因为女神的要求之间优先级是相同的,如果有女神占了一段时间,那么其它女神也不能占用
}
else{
if(tr[][]>=x){ //只要女神树上能满足,此时即使基友树上发生冲突也不管,如果需要占用基友时间,直接强制更新,体现了女神的高优先级
int ans=query(,,n,x,);
printf("%d,don't put my gezi\n", ans);
update(,,n,ans,ans+x-,,);
update(,,n,ans,ans+x-,,);
}
else printf("wait for me\n");
}
}
else{
scanf("%d%d", &x, &y);
printf("I am the hope of chinese chengxuyuan!!\n");
update(,,n,x,y,,); //同时将基友树和女神树上的要求全部清除
update(,,n,x,y,,);
}
}
}
return ;
}


2018-10-01

HDU 4553 约会安排 (区间合并)【线段树】的更多相关文章

  1. HDU 4553 约会安排(线段树区间合并+双重标记)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553 题目大意:就是有三种操作: ①DS x,安排一段长度为x的空闲时间跟屌丝一起,输出这段时间的起点 ...

  2. HDU - 4553 约会安排(区间合并)

    https://cn.vjudge.net/problem/HDU-4553 Description 寒假来了,又到了小明和女神们约会的季节.  小明虽为屌丝级码农,但非常活跃,女神们常常在小明网上的 ...

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

      题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553 算是poj3667的加强版,建立两颗线段树,一个是DS区间,另一个是NS区间.那么根据题意, ...

  4. hdu 4553 约会安排

    约会安排 http://acm.hdu.edu.cn/showproblem.php?pid=4553 Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  5. BZOJ 2243:染色(树链剖分+区间合并线段树)

    [SDOI2011]染色Description给定一棵有n个节点的无根树和m个操作,操作有2类:1.将节点a到节点b路径上所有点都染成颜色c:2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认 ...

  6. HDU 1540 区间合并线段树

    题目大意: 就是给定一堆位置,进行删除还原,最后找到 t 位置上的最大连续位置 #include <cstdio> #include <cstring> #include &l ...

  7. HDU 5029 Relief grain(离线+线段树+启发式合并)(2014 ACM/ICPC Asia Regional Guangzhou Online)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5029 Problem Description The soil is cracking up beca ...

  8. hdu 5700区间交(线段树)

    区间交 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...

  9. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

随机推荐

  1. Confluence 6 PostgreSQL 设置准备

    请查看 Supported Platforms 页面来获得 Confluence 系统支持的 PostgreSQL 数据库版本.你需要在安装 Confluence 之前升级你的 PostgreSQL ...

  2. selenium+python之 辨识alert、window以及操作

    1.分辨 首先区别下alert.window和伪装对话框: alert,浏览器弹出框,一般是用来确认某些操作.输入简单的text或用户名.密码等,根据浏览器的不同,弹出框的样式也不一样,不过都是很简单 ...

  3. kafka 的安装部署

    Kafka 的简介: Kafka 是一款分布式消息发布和订阅系统,具有高性能.高吞吐量的特点而被广泛应用与大数据传输场景.它是由 LinkedIn 公司开发,使用 Scala 语言编写,之后成为 Ap ...

  4. BeautifulSoup的基本用法

    # -*- coding:UTF-8 -*- from urllib import request from bs4 import BeautifulSoup import re import sys ...

  5. 小学生都看得懂的C语言入门(2): 判别 循环的一些应用实例

    1.bool 类型 定义bool类型之前需要导入#include <stdbool.h> #include <stdio.h> #include <stdbool.h&g ...

  6. 20165314 2016-2017-2 《Java程序设计》第7周学习总结

    20165314 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 MySQL数据库管理系统 连接MySQL数据库 JDBC 批处理 代码托管

  7. HTML中body元素的属性

    body元素的属性 属性 描述 text 设定页面文字颜色 bgcolor 设定页面背景颜色 background 设定页面背景图像 bgproperties 设定页面的背景图像为固定状态(不随页面的 ...

  8. 怎么加密接口防止,API外部调用?

    服务器端与客户端各自会存储一个TOKEN,这个TOKEN我们为了防止反编译是用C语言来写的一个文件并做了加壳和混淆处理.在客户端访问服务器API任何一个接口的时候,客户端需要带上一个特殊字段,这个字段 ...

  9. appium+python测试app使用相对坐标定位元素

    我们获取到的是绝对坐标,如果换一个屏幕分辨率不同的手机那这个坐标自然会发生变化,要实现不同手机均能实现点击同一控件自然要用到相对坐标了,具体方法如下: 1.获取当前空间的绝对坐标(x1,y1),开启指 ...

  10. 集腋成裘-01 sublime常用的快捷键

    sublime使用的快捷键 1:Html 结构代码  : Html:xt + tab键 2:补全标签代码   : tab键 3:快速复制一行代码 : Ctrl+shift+d 4:快速选中一行代码 : ...