题目大意:
有一排标号1-N的房间。
操作一:询问是不是有连续长度为a的空房间,有的话住进最左边(占用a个房间)
操作二:将[a,a+b-1]的房间清空(腾出b个房间)
思路:记录每个区间中“靠左”“靠右”“中间”的空房间
线段树操作:update:区间替换
query:询问满足条件的最左端点

题目链接:

http://vjudge.net/problem/viewProblem.action?id=10354

题目操作:

因为这里找从最左边住起的房间,所以这里不能像常规地写query函数那样写了,终于发现自己只会套模板的下场的悲哀了,智商拙计啊T T

而且你在query函数,因为要尽可能找左边的房间,所以要从左边先递归

1.

int query(int cur,int x,int y,int w)
{
    int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1;
    if(x==y) return x;  //这里是表示找到树的底层无叶节点了就结束函数,同时也防止找不到点,其实这里如果找不到所求点的话,会不断进入右子树最后抵达最大的子节点返回
    pushdown(cur,x,y);
    if(mc[cur<<1]>=w) return query(ls,x,mid,w);  //如果左侧能找到满足的点,我们不断朝左侧进行递归
    else if(rc[cur<<1]+lc[cur<<1|1]>=w) return mid-rc[cur<<1]+1;//左侧不成立我们在开始找中间并在一起形成的房间的最左侧点
    return query(rs,mid+1,y,w);  //左侧中间都不成立,那么只能进入右子树进行找点
}
因为这个query函数必然有返回值,所以,我们在主函数中必须先进行判断能否找到适合的一连串的房间,然后再进行ans=query(1,1,n,w)操作以及后面的房间入住的覆盖操作。

这个判断很简单 1为线段树根节点,所以mc[1]其实是最大的连续最长房间,if(mc[1]>=w)这个判断执行就可以了

这里介绍一下puts("0"):
puts()函数用来向标准输出设备(屏幕)写字符串并换行,其调用方式为,puts(s);其中s为字符串字符(字符串数组名或字符串指针)。

所以这道题puts("0");就输出了不存在的情况

2.

当然我也可以换种方式在query的函数里面进行一下小小的修改,使得它在不能找到房间的时候输出-1;

int query(int cur,int x,int y,int w)
{
    int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1;
    if(x==y) return mc[cur]<w?-:x; //在这修改一下,然后直接在main函数中判断为-1,那么输出0即可
    pushdown(cur,x,y);
    if(mc[cur<<1]>=w) return query(ls,x,mid,w);
    else if(rc[cur<<1]+lc[cur<<1|1]>=w) return mid-rc[cur<<1]+1;
    return query(rs,mid+1,y,w);
}

总代码如下:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. #define N 50010
  6. #define L ls,x,mid
  7. #define R rs,mid+1,y
  8. int rev[N<<],lc[N<<],rc[N<<],mc[N<<];
  9. void update(int cur,int x,int y)
  10. {
  11. int mid=(x+y)/,ls=cur<<,rs=cur<<|;
  12. lc[cur]=lc[ls],rc[cur]=rc[rs];
  13. mc[cur]=max(mc[ls],mc[rs]);
  14. mc[cur]=max(mc[cur],rc[ls]+lc[rs]);
  15. if(lc[ls]==mid-x+) lc[cur]=lc[ls]+lc[rs];
  16. if(rc[rs]==y-mid) rc[cur]=rc[rs]+rc[ls];
  17. }
  18. void build(int cur,int x,int y)
  19. {
  20. int mid=(x+y)/,ls=cur<<,rs=cur<<|;
  21. rev[cur]=-;
  22. if(x==y){
  23. lc[cur]=rc[cur]=mc[cur]=;
  24. return;
  25. }
  26. build(ls,x,mid);
  27. build(rs,mid+,y);
  28. update(cur,x,y);
  29. }
  30. void pushdown(int cur,int x,int y)
  31. {
  32. int mid=(x+y)/,ls=cur<<,rs=cur<<|;
  33. if(rev[cur]!=-){
  34. if(rev[cur]==){
  35. rev[ls]=rev[rs]=;
  36. lc[ls]=rc[ls]=mc[ls]=lc[rs]=rc[rs]=mc[rs]=;
  37. rev[cur]=-;
  38. }
  39. else if(rev[cur]==){
  40. rev[ls]=rev[rs]=;
  41. lc[ls]=rc[ls]=mc[ls]=mid-x+;
  42. lc[rs]=rc[rs]=mc[rs]=y-mid;
  43. rev[cur]=-;
  44. }
  45. }
  46. }
  47. void change(int cur,int x,int y,int s,int t,int v)
  48. {
  49. int mid=(x+y)/,ls=cur<<,rs=cur<<|;
  50. if(x>=s&&y<=t){
  51. rev[cur]=v;
  52. lc[cur]=rc[cur]=mc[cur]=v?:y-x+;
  53. return;
  54. }
  55. pushdown(cur,x,y);
  56. if(mid>=s) change(ls,x,mid,s,t,v);
  57. if(mid+<=t) change(rs,mid+,y,s,t,v);
  58. update(cur,x,y);
  59. }
  60. int query(int cur,int x,int y,int w)
  61. {
  62. int mid=(x+y)>>,ls=cur<<,rs=cur<<|;
  63. if(x==y) return x;
  64. pushdown(cur,x,y);
  65. if(mc[cur<<]>=w) return query(ls,x,mid,w);
  66. else if(rc[cur<<]+lc[cur<<|]>=w) return mid-rc[cur<<]+;
  67. return query(rs,mid+,y,w);
  68. }
  69. int main()
  70. {
  71. int n,m,op,a,b;
  72. while(scanf("%d%d",&n,&m)!=EOF){
  73. build(,,n);
  74. for(int i=;i<m;i++){
  75. scanf("%d",&op);
  76. if(op==){
  77. scanf("%d",&a);
  78. if(mc[]<a) puts("");
  79. else{
  80. int ans=query(,,n,a);
  81. printf("%d\n",ans);
  82. change(,,n,ans,ans+a-,);
  83. }
  84. }
  85. else{
  86. scanf("%d%d",&a,&b);
  87. change(,,n,a,a+b-,);
  88. }
  89. }
  90. }
  91. return ;
  92. }

POJ 3667 线段树的区间合并简单问题的更多相关文章

  1. POJ 3667 线段树区间合并裸题

    题意:给一个n和m,表示n个房间,m次操作,操作类型有2种,一种把求连续未租出的房间数有d个的最小的最左边的房间号,另一个操作时把从x到x+d-1的房间号收回. 建立线段树,值为1表示未租出,0为租出 ...

  2. 线段树的区间合并 B - LCIS

    B - LCIS HDU - 3308 这个是一个很简单很明显的线段树的区间合并,不过区间合并的题目都还是有点难写,建议存个板子. #include <cstdio> #include & ...

  3. 线段树:CDOJ1592-An easy problem B (线段树的区间合并)

    An easy problem B Time Limit: 2000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Pr ...

  4. CodeForces - 587E[线段树+线性基+差分] ->(线段树维护区间合并线性基)

    题意:给你一个数组,有两种操作,一种区间xor一个值,一个是查询区间xor的结果的种类数 做法一:对于一个给定的区间,我们可以通过求解线性基的方式求出结果的种类数,而现在只不过将其放在线树上维护区间线 ...

  5. Codeforces Round #222 (Div. 1) D. Developing Game 线段树有效区间合并

    D. Developing Game   Pavel is going to make a game of his dream. However, he knows that he can't mak ...

  6. POJ 3667 & HDU 3308 & HDU 3397 线段树的区间合并

    看到讲课安排上 线段树有一节课"区间合并" 我是迷茫的 因为并没有见过 然后了解了一下题目 发现以前写过 还是很麻烦的树链剖分 大概是 解决带修改的区间查询"连续问题&q ...

  7. POJ 3667 线段树区间合并

    http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html 用线段树,首先要定义好线段树的节点信息,一般看到一个问题,很难很 ...

  8. POJ 2750 Potted Flower(线段树的区间合并)

    点我看题目链接 题意 : 很多花盆组成的圆圈,每个花盆都有一个值,给你两个数a,b代表a位置原来的数换成b,然后让你从圈里找出连续的各花盆之和,要求最大的. 思路 :这个题比较那啥,差不多可以用DP的 ...

  9. HDU_3308_线段树_区间合并

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

随机推荐

  1. Mysql选择合适的存储引擎

    Myisam:默认的mysql插件式存储引擎.如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性.并发性要求不是很高,那么选择这个存储引擎是非常合适的.Myisam是在we ...

  2. ISCSI存储

    slave-147作为服务端 需要安装的软件 [root@slave-147 ~]# yum install -y scsi-target-utils slave-148和slave-149作为客户端 ...

  3. HBase表结构设计--练习篇

    一.表结构操作 1.建立一个表scores,有两个列族grad和course [hadoop@weekend01 ~]$ hbase shell hbase(main):006:0> creat ...

  4. RedHat改yum源免费使用CentOS源

    linux默认是安装了yum软件的,但是由于激活认证的原因让redhat无法直接进行yum安装一些软件 如果我们需要在redhat下直接yum安装软件,我们只用把yum的源修改成CentOS的就好了, ...

  5. archsummit_bj2016

    http://bj2016.archsummit.com/schedule 大会日程 2016年12月02日,星期五 7:45-9:00 签到 8:45-9:00 开始入场 9:00-9:30 开场致 ...

  6. P2629 好消息,坏消息

    题目描述 uim在公司里面当秘书,现在有n条消息要告知老板.每条消息有一个好坏度,这会影响老板的心情.告知完一条消息后,老板的心情等于之前老板的心情加上这条消息的好坏度.最开始老板的心情是0,一旦老板 ...

  7. 【前端】jQurey Plugin

    ; (function ($, window, document, undefined) { "use strict"; var defaults = { name: " ...

  8. iOS之tableView性能优化/tableView滑动卡顿?

    本文围绕以下几点展开tableView性能优化的论述? 1.UITableViewCell重用机制? 2.tableView滑动为什么会卡顿? 3.优化方法? 4.总结 1.UITableViewCe ...

  9. 如何正确理解关键字"with"与上下文管理器

    转自:https://foofish.net/with-and-context-manager.html 如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 “with” 关键字的语句,它通 ...

  10. 设计 REST API 的13个最佳实践

    写在前面 之所以翻译这篇文章,是因为自从成为一名前端码农之后,调接口这件事情就成为了家常便饭,并且,还伴随着无数的争论与无奈.编写友好的 restful api 不论对于你的同事,还是将来作为第三方服 ...