操作1,的关键是找到第一只和最后一只空花瓶,完全可以利用二分法查找,找第一只花瓶可以在[X,N]内查找,第一个位置pos1,最后一只花瓶则在[POS1,N]中找,然后更新[POS1,POS2],全部置1即可

代码:

  1. #include<iostream>
  2. using namespace std;
  3. const int N = 5e4 + 5;
  4. struct node {
  5. int lazy;
  6. int sum; //sum代表空花瓶的数量
  7. }tree[N<<2];
  8. int ls(int i) { return i << 2; }
  9. int rs(int i) { return i << 2 | 1; }
  10. int t, n, m, x, y, k;
  11. //以下四个函数都是线段树的基本操作
  12. void pushdown(int id, int l, int r) {
  13. if (tree[id].lazy == -1) { return; }
  14. int mid = (l + r) >> 1;
  15. tree[ls(id)].sum = (mid - l + 1) * tree[id].lazy;
  16. tree[rs(id)].sum = (r - mid) * tree[id].lazy;
  17. tree[ls(id)].lazy = tree[rs(id)].lazy = tree[id].lazy;
  18. tree[id].lazy = -1;
  19. }
  20. void pushup(int id) {
  21. tree[id].sum = tree[ls(id)].sum + tree[rs(id)].sum;
  22. }
  23. void build(int id, int l, int r) {
  24. if (l == r) {
  25. tree[id].lazy = -1;
  26. tree[id].sum = 0;
  27. }
  28. int mid = (l + r) >> 1;
  29. build(ls(id), l, mid);
  30. build(rs(id), mid + 1, r);
  31. tree[id].lazy = -1;
  32. pushup(id);
  33. }
  34. int query(int id, int l, int r, int x, int y) {
  35. if (x <= l && y >= r) return tree[id].sum;
  36. int ans = 0;
  37. pushdown(id, l, r);
  38. int mid = (l + r) >> 1;
  39. if (x <= mid) ans += query(ls(id), l, mid, x, y);
  40. if (y > mid) ans += query(rs(id), mid + 1, r, x, y);
  41. return ans;
  42. }
  43. void update(int id, int l, int r, int x, int y, int d) { //d=1代表花瓶是空的,d=0代表花瓶是满的
  44. if (x <= l && y >= r) {
  45. tree[id].sum = (r - l + 1) * d;
  46. tree[id].lazy = d;
  47. return;
  48. }
  49. pushdown(id, l, r);
  50. int mid = (l + r) >> 1;
  51. if (x <= mid) update(ls(id), l, mid, x, y, d);
  52. if (y > mid) update(rs(id), mid + 1, r, x, y, d);
  53. pushup(id);
  54. }
  55. int binarysearch(int x, int n, int f) {
  56. int l = x, int r = n;
  57. while (l < r) {
  58. int mid = (l + r) >> 1;
  59. int t = query(1, 1, n, x, mid); //查找左边部分,从左边判断第f个空花瓶是在左边还是右边
  60. if (t >= f) r = mid;
  61. else l = mid + 1;
  62. }
  63. return r;
  64. }
  65. int main() {
  66. cin >> t;
  67. while (t--) {
  68. cin >> n >> m;
  69. build(1, 1, n);
  70. for (int i = 1; i <= m; i++) {
  71. cin >> k >> x >> y;
  72. if (k == 1) {
  73. x++; //保证区间为[1,N]
  74. //首先查询[X,N]中是否有空花瓶
  75. int t = query(1, 1, n, x, n);
  76. if (t == 0) {
  77. cout << "Can not put any one" << endl;
  78. }
  79. else {
  80. t = min(y, t); //计算需要插花数量,此时的y代表收到花的数量
  81. int s = binarysearch(x, n, 1); //搜索第一个空花瓶
  82. int t = binarysearch(s, n, t); //搜索最后一个空花瓶
  83. cout << s - 1 << " " << t - 1 << endl;
  84. update(1, 1, n, s, t, 0);
  85. }
  86. }
  87. else {
  88. x++; y++;
  89. int t = query(1, 1, n, x, y);
  90. update(1, 1, n, x, y, 1);
  91. cout << y - x + 1 - t;
  92. }
  93. }
  94. cout << endl;
  95. }
  96. return 0;
  97. }

线段树与二分操作 vases and flowers ——hdu 4614的更多相关文章

  1. L - Vases and Flowers HDU - 4614 线段树+二分

    题意 给出一排空花瓶 有两种操作  1是 从A花瓶开始放F朵花 如果当前瓶有花就跳过前往下一个 直到花用完或者 瓶子到了最后一个为止 输出 成功放花的第一个和最后一个  如果没有输出 can not. ...

  2. L - Vases and Flowers - hdu 4614(区间操作)

    题意:有两种操作,第一种从A开始插花,如果有花就跳到下一个,然后输出最后一个花瓶的编号,如果花瓶不够把多余的花丢掉.操作2把区间清空 分析:很明显的线段树操作,就是插花的时候麻烦一下,需要先找出来他剩 ...

  3. luoguP6619 [省选联考 2020 A/B 卷]冰火战士(线段树,二分)

    luoguP6619 [省选联考 2020 A/B 卷]冰火战士(线段树,二分) Luogu 题外话1: LN四个人切D1T2却只有三个人切D1T1 很神必 我是傻逼. 题外话2: 1e6的数据直接i ...

  4. 线段树区间更新操作及Lazy思想(详解)

    此题题意很好懂:  给你N个数,Q个操作,操作有两种,‘Q a b ’是询问a~b这段数的和,‘C a b c’是把a~b这段数都加上c. 需要用到线段树的,update:成段增减,query:区间求 ...

  5. 【BZOJ4552】排序(线段树,二分答案)

    [BZOJ4552]排序(线段树,二分答案) 题面 BZOJ 题解 好神的题啊 直接排序我们做不到 怎么维护? 考虑一下,如果我们随便假设一个答案 怎么检验它是否成立? 把这个数设成\(1\),其他的 ...

  6. hdu 3436 线段树 一顿操作

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  7. CodeForces 914DBash and a Tough Math Puzzle(线段树的骚操作)

    D. Bash and a Tough Math Puzzle time limit per test 2.5 seconds memory limit per test 256 megabytes ...

  8. BZOJ3110 [Zjoi2013]K大数查询 树套树 线段树 整体二分 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3110 题意概括 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位 ...

  9. LOJ 2585 「APIO2018」新家 ——线段树分治+二分答案

    题目:https://loj.ac/problem/2585 算答案的时候要二分! 这样的话,就是对于询问位置 x ,二分出一个最小的 mid 使得 [ x-mid , x+mid ] 里包含所有种类 ...

  10. BZOJ.4552.[HEOI2016/TJOI2016]排序(线段树合并/二分 线段树)

    题目链接 对于序列上每一段连续区间的数我们都可以动态开点建一棵值域线段树.初始时就是\(n\)棵. 对于每次操作,我们可以将\([l,r]\)的数分别从之前它所属的若干段区间中分离出来,合并. 对于升 ...

随机推荐

  1. 「比赛记录」CF Round 954 (Div. 3)

    Codeforces Round 954 (Div. 3) 题目列表: A. X Axis B. Matrix Stabilization C. Update Queries D. Mathemati ...

  2. SQL:聚集索引和非聚集索引

    聚集(clustered)索引,也叫聚簇索引 定义:数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序相同,一个表中只能拥有一个聚集索引. 注:第一列的地址表示该行数据在磁盘中的物理地址,后面三列 ...

  3. JavaScript 监听组合按键

    JavaScript监听组合按键   by:授客 QQ:1033553122 1.   思路 如图,通过监听并打印键盘keydown事件,得到图示内容,观察发现, 当按下的组合键包含Ctrl键时,ct ...

  4. MFC 完全自定义控件

    头文件 #pragma once #include "pch.h" class CGridCtrl : public CWnd { public: void Create(CWnd ...

  5. 【Java】【常用类】Comparable 可比较接口 Comparator 比较器接口

    我们需要对对象进行排序,但是对象不是像基本类型的那样,是具体的数值 如果要对对象比较,需要实现两个接口的任意一个即可 Comparable 可比较接口 Comparator 比较器接口 String包 ...

  6. 【Java】JDBC Part5 DataSource 连接池操作

    JDBC Part5 DataSource 连接池操作 - javax.sql.DataSource 接口,通常由服务器实现 - DBCP Tomcat自带相对C3P0速度较快,但存在BUG,已经不更 ...

  7. python科学计算:加速库numba —— 安装和试用

    安装(anaconda环境下) conda install numba Demo代码: from numba import jit from numpy import arange import nu ...

  8. 汽车模具设计软件 —— 达索集团的Catia

    相关: https://www.3ds.com/zh/products-services/catia/ Catia是Dassault Systems公司推出的产品造型软件,广泛应用于汽车.航空.机械等 ...

  9. 宝塔环境安装redis

    参考: http://www.bt.cn/Help/Find?id=92 步骤: 1. 在安装宝塔时 PHP 版本选 7.0: 2. 安装 redis:wget http://125.88.182.1 ...

  10. 中电信翼康济世数据中台基于Apache SeaTunnel构建数据集成平台经验分享

    作者 | 中电信翼康工程师 代来编辑 | Debra Chen 一. 引言 Apache SeaTunnel作为一个高性能.易用的数据集成框架,是快速落地数据集成平台的基石.本文将从数据中台战略背景. ...