HDU 4553 约会安排 (区间合并)【线段树】

时间:2022-09-27 19:54:35

<题目链接>

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

    题目链接: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:染色(树链剖分&plus;区间合并线段树)

    [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(离线&plus;线段树&plus;启发式合并)(2014 ACM&sol;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区间交&lpar;线段树&rpar;

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

  9. hdu 5274 Dylans loves tree&lpar;LCA &plus; 线段树&rpar;

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

随机推荐

  1. ACM知识点

    基础算法 高精 模拟 分治 贪心 排序 DFS 迭代加深搜索 BFS 双向BFS 动态规划 DAG上DP 树上DP 线性DP 图算法 最短路 FLYD DJATL BF 最大流 Dinic ISAP ...

  2. vba 笔记

    1.PlanWS5.Range("D5:E13").Copy   复制PlanWS5.Range("G5:H13").PasteSpecial Paste:=x ...

  3. &lbrack;Leetcode&rsqb; Merge Intevals

    Question: Given a collection of intervals, merge all overlapping intervals. For example,Given [1,3], ...

  4. 阿里云Centos7使用yum安装MySQL5&period;6的正确姿势

    阿里云Centos7使用yum安装MySQL5.6 阿里云Centos7使用yum安装MySQL5.6 前言:由于某些不可抗力,我要在自己的阿里云服务器上搭建hadoop+hive+mysql+tom ...

  5. &lbrack;置顶&rsqb; 创建GitHub技术博客全攻略

    [置顶] 创建GitHub技术博客全攻略 分类: GitHub2014-07-12 13:10 19710人阅读 评论(21) 收藏 举报 githubio技术博客网站生成 说明: 首先,你需要注册一 ...

  6. 基于&period;net开发chrome核心浏览器【二】

    原文:基于.net开发chrome核心浏览器[二] 一: 上一篇的链接: 基于.net开发chrome核心浏览器[一] 二: 相关资源介绍: chrome Frame: 让IE有一颗chrome的心, ...

  7. python——vs2017安装python库时&comma;提示pip指令问题。

    需要跟新pip指令 方法: 第一步:打开vs2017 后新建一个python 文件 后面如图 点击红色部分 2.在框中输入pip之后更新即可 如图 3.问题解决 倘若还有问题 欢迎分享

  8. 使用IE浏览提示:该页面无法显示

    问题描述: 我们有一个外部招聘的网站,DBA反馈新版上线过后首页集成的登录部分页面无法打开,一直显示“该页面无法显示”! 问题排查: 1.因为我本身也不是负责这一块的业务,刚开始以为是网站本身程序的问 ...

  9. Python实例---beautifulsoup小Demo

    豆瓣 # coding:utf - 8 from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen( ...

  10. Android点击事件

    Android点击事件 备注 全局实现View.OnClickListener 或许需要将MainActivity设置为public 注册事件 btn_login.setOnClickListener ...