参考:https://blog.csdn.net/u010336344/article/details/53034372

神一样的线段树

线段树上维护:ll从左开始最长空段;rr从右开始最长空段;len区间中最长空段;tg:-1不全是空的,0区间内全是空的,1区间内全是满的;lz下传标记:-1没标记,1下传满的,0下传空的

修改的时候,修改到一整个区间,就把lz和tg改了,ll、rr、len全改成r-l+1或者0

然后下传标记的时候同上

向上合并的时候,先把左右区间的ll、rr穿给当前区间,然后根据左右区间的tg是否为0(全空)来扩大当前区间的ll、rr;tg根据左右区间tg更改;len从左区间len、右区间len和左区间rl+右区间ll中取max

查询的时候优先查左边即可,像二分一样在树上跳

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. const int N=100005;
  5. int n,m;
  6. struct xds
  7. {
  8. int l,r,ll,rl,tg,len,lz;
  9. }t[N<<1];
  10. int read()
  11. {
  12. int r=0,f=1;
  13. char p=getchar();
  14. while(p>'9'||p<'0')
  15. {
  16. if(p=='-')
  17. f=-1;
  18. p=getchar();
  19. }
  20. while(p>='0'&&p<='9')
  21. {
  22. r=r*10+p-48;
  23. p=getchar();
  24. }
  25. return r*f;
  26. }
  27. void pd(int ro)
  28. {
  29. if(t[ro].lz!=-1)
  30. {
  31. if(t[ro].lz==1)
  32. {
  33. t[ro<<1].rl=t[ro<<1].ll=t[ro<<1].len=0;
  34. t[ro<<1|1].rl=t[ro<<1|1].ll=t[ro<<1|1].len=0;
  35. }
  36. else
  37. {
  38. t[ro<<1].rl=t[ro<<1].ll=t[ro<<1].len=t[ro<<1].r-t[ro<<1].l+1;
  39. t[ro<<1|1].rl=t[ro<<1|1].ll=t[ro<<1|1].len=t[ro<<1|1].r-t[ro<<1|1].l+1;
  40. }
  41. t[ro<<1].tg=t[ro<<1|1].tg=t[ro].tg;
  42. t[ro<<1].lz=t[ro<<1|1].lz=t[ro].lz;
  43. t[ro].lz=-1;
  44. }
  45. }
  46. void ud(int ro)
  47. {
  48. if(t[ro<<1].tg==t[ro<<1|1].tg)
  49. t[ro].tg=t[ro<<1].tg;
  50. else
  51. t[ro].tg=-1;
  52. t[ro].ll=t[ro<<1].ll;
  53. t[ro].rl=t[ro<<1|1].rl;
  54. if(!t[ro<<1].tg)
  55. t[ro].ll+=t[ro<<1|1].ll;
  56. if(!t[ro<<1|1].tg)
  57. t[ro].rl+=t[ro<<1].rl;
  58. t[ro].len=max(max(t[ro<<1].len,t[ro<<1|1].len),t[ro<<1].rl+t[ro<<1|1].ll);
  59. }
  60. void build(int ro,int l,int r)
  61. {
  62. t[ro].l=l,t[ro].r=r,t[ro].len=t[ro].ll=t[ro].rl=r-l+1,t[ro].lz=-1;
  63. if(l==r)
  64. return;
  65. int mid=(l+r)>>1;
  66. build(ro<<1,l,mid);
  67. build(ro<<1|1,mid+1,r);
  68. }
  69. void update(int ro,int l,int r,int k)
  70. {
  71. if(t[ro].l==l&&t[ro].r==r)
  72. {
  73. if(k)
  74. t[ro].rl=t[ro].ll=t[ro].len=0;
  75. else
  76. t[ro].rl=t[ro].ll=t[ro].len=r-l+1;
  77. t[ro].tg=t[ro].lz=k;
  78. return;
  79. }
  80. pd(ro);
  81. int mid=(t[ro].l+t[ro].r)>>1;
  82. if(r<=mid)
  83. update(ro<<1,l,r,k);
  84. else if(l>mid)
  85. update(ro<<1|1,l,r,k);
  86. else
  87. update(ro<<1,l,mid,k),update(ro<<1|1,mid+1,r,k);
  88. ud(ro);
  89. }
  90. int ques(int ro,int k)
  91. {
  92. int re=-1;
  93. while(t[ro].l&&t[ro].len>=k)
  94. {
  95. if(t[ro].ll>=k)
  96. {
  97. re=t[ro].l;
  98. break;
  99. }
  100. if(t[ro<<1].len>=k)
  101. ro<<=1;
  102. else
  103. {
  104. if(t[ro<<1].rl!=0&&t[ro<<1].rl+t[ro<<1|1].ll>=k)
  105. {
  106. re=t[ro<<1].r-t[ro<<1].rl+1;
  107. break;
  108. }
  109. else
  110. ro=ro<<1|1;
  111. }
  112. }
  113. return re;
  114. }
  115. int main()
  116. {
  117. n=read(),m=read();
  118. build(1,1,n);
  119. while(m--)
  120. {
  121. int o=read();
  122. if(o==1)
  123. {
  124. int x=read(),now=ques(1,x);
  125. if(now!=-1)
  126. {
  127. printf("%d\n",now);
  128. update(1,now,now+x-1,1);
  129. }
  130. else
  131. puts("0");
  132. }
  133. else
  134. {
  135. int x=read(),y=read();
  136. update(1,x,x+y-1,0);
  137. }
  138. }
  139. return 0;
  140. }

bzoj 1593: [Usaco2008 Feb]Hotel 旅馆【线段树】的更多相关文章

  1. BZOJ 1593: [Usaco2008 Feb]Hotel 旅馆 [线段树]

    传送门 题意: 操作1:找长为$len$的空区间并填满,没有输出$0$ 操作2:将$[l,r]$之间的区间置空 我真是太弱了这种线段树还写了一个半小时,中间为了查错手动模拟了$30min$线段树操作, ...

  2. bzoj1593 [Usaco2008 Feb]Hotel 旅馆(线段树)

    1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 758  Solved: 419[Submit ...

  3. 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并

    题目描述 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N & ...

  4. BZOJ 1593: [Usaco2008 Feb]Hotel 旅馆

    Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 &l ...

  5. 1593: [Usaco2008 Feb]Hotel 旅馆

    1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 391  Solved: 228[Submit ...

  6. 【BZOJ】1593: [Usaco2008 Feb]Hotel 旅馆

    [算法]线段树(经典线段树上二分) [题意]n个房间,m个询问,每次订最前的连续x个的空房间,或退订从x开始y个房间,求每次订的最左房间号. [题解]关键在于找连续x个空房间,经典二分. 线段树标记s ...

  7. 线段树||BZOJ1593: [Usaco2008 Feb]Hotel 旅馆||Luogu P2894 [USACO08FEB]酒店Hotel

    题面:P2894 [USACO08FEB]酒店Hotel 题解:和基础的线段树操作差别不是很大,就是在传统的线段树基础上多维护一段区间最长的合法前驱(h_),最长合法后驱(t_),一段中最长的合法区间 ...

  8. 【最长连续零 线段树】bzoj1593: [Usaco2008 Feb]Hotel 旅馆

    最长连续零的线段树解法 Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负 责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大 ...

  9. BZOJ1593 [Usaco2008 Feb]Hotel 旅馆

    裸上线段树,就是记的东西有点多... 每个点记区间左端最长0,右端最长0,中间最长0,和tag表示是否全为0/1 直接更新就好,查询的时候先查左儿子,然后查中间,最后查右儿子... /******** ...

随机推荐

  1. 【Codeforces 1041D】Glider

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 二分. 枚举每一个上升区的起始位置作为起点(这样做肯定是最优的),然后如果没有掉在地上的话就尽量往右二分(只有上升区之间的间隙会让他往下掉) ...

  2. Leetcode 208.实现前缀树

    实现前缀树 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = new Trie(); trie.insert ...

  3. linux shell 获得当前程序的路径

    filepath=$(cd "$(dirname "$0")"; pwd) 脚本文件的绝对路径存在了环境变量filepath中,可以用 echo $filepa ...

  4. SOJ 2800_三角形

    真的是O不是0[看了discuss才发现.....一个大写的蠢 [题意]多个黑白三角形组成的倒三角,求白三角形组成的最大倒三角的面积 [分析]由于问的是倒三角个数,所以只需看与行数奇偶性相同的白色倒三 ...

  5. 【electron系列之一】创建右下角通知栏小图标

    electron 用Tray对象来实现右下角通知栏小图标 一.先引入app, BrowserWindow来实现浏览器功能,接着引入Tray, Menu来实现右下角 二. new Tray('./pag ...

  6. Spring Cloud体系实现标签路由

    如果你正在使用Spring Cloud体系,在实际使用过程中正遇到以下问题,可以阅读本文章的内容作为后续你解决这些问题的参考,文章内容不保证无错,请务必仔细思考之后再进行实践. 问题: 1,本地连上开 ...

  7. Memcached的几种Java客户端(待实践)

    其实现在来尝试Memcached的客户端估计会有点过气,因为现在大势基本都在Redis那边. Memcached Client目前有3种: Memcached Client for Java(已经停止 ...

  8. ssh forwarding 配置

    假设有服务器A,属于某一内网,无法直接登录. A: 10.0.1.48 root/password@a 但我们有一台跳板机器可以访问该Server A B: 10.0.2.48 root/passwo ...

  9. fuse-dfs挂载hdfs实录

    部署安装了最新稳定版hadoop2.2.0.然后在网上找来fuse-dfs编译教程.可是最后失败了.至今原因未知--,错误描写叙述为:Transport endpoint is not connect ...

  10. Redis官网下载步骤(含windows版)

    ①.百度redis ,进入官网 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...