<题目链接>

题目大意:

有n个花瓶,每个花瓶中只能放一朵花。两种操作,一种是从A开始放F朵花,如果有的花瓶中已经有花则跳过这个花瓶,往下一个花瓶放;第二种是将区间[A,B]之间花瓶中的花清空。如果是第一种操作,输出这次放的花的左右端点;如果是第二种操作,输出这次总共清理出了多少支花。

解题分析:

本题可以很巧妙的将这两种操作全部转化为区间修改,毫无疑问,第二种操作肯定是区间修改;对于第一种操作,可以用二分答案将x后的第num个空瓶的坐标查找出来,因为二分答案时需要直接查询指定区间内空瓶的数量,所以线段树叶子节点维护一个值,代表该区间空瓶的数量,得到第一个和最后一个空瓶的数量后,直接对该区间进行区间修改,将空瓶数量全部置0即可。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5
 6 #define Lson rt<<1,l,mid
 7 #define Rson rt<<1|1,mid+1,r
 8 const int M =5e4+5;
 9 int n,m;
10 int tr[M<<2],lazy[M<<2];
11 //lazy[rt]初始化为-1,lazy[rt]==0,代表这个区间瓶子全满,lazy[rt]==1,代表这个区间瓶子全空
12 void Pushup(int rt){ tr[rt]=tr[rt<<1]+tr[rt<<1|1]; }
13 void Pushdown(int rt,int len){
14     if(lazy[rt]!=-1){
15         int tmp=lazy[rt];
16         lazy[rt<<1]=tmp;
17         lazy[rt<<1|1]=tmp;
18         tr[rt<<1]=(len-(len>>1))*tmp;
19         tr[rt<<1|1]=(len>>1)*tmp;
20         lazy[rt]=-1;
21     }
22 }
23 void build(int rt,int l,int r){
24     lazy[rt]=-1;
25     if(l==r){
26         tr[rt]=1;
27         return;
28     }
29     int mid=(l+r)>>1;
30     build(Lson);
31     build(Rson);
32     Pushup(rt);
33 }
34 void update(int rt,int l,int r,int L,int R,int c){
35     if(L<=l&&r<=R){
36         lazy[rt]=c;
37         tr[rt]=(r-l+1)*c;
38         return;
39     }
40     Pushdown(rt,r-l+1);
41     int mid=(l+r)>>1;
42     if(L<=mid)update(Lson,L,R,c);
43     if(R>mid)update(Rson,L,R,c);
44     Pushup(rt);
45 }
46 int query(int rt,int l,int r,int L,int R){    //查询指定区间的空瓶数量
47     if(L<=l&&r<=R)return tr[rt];
48     Pushdown(rt,r-l+1);
49     int mid=(l+r)>>1;
50     int ans=0;
51     if(L<=mid)ans+=query(Lson,L,R);
52     if(R>mid)ans+=query(Rson,L,R);
53     return ans;
54 }
55 int bin_search(int x,int num){     //二分答案,查找从x开始的第num个空瓶子的下标
56     int l=x,r=n,ans;
57     while(l<=r){
58         int mid=(l+r)>>1;
59         if(query(1,1,n,x,mid)>=num)ans=mid,r=mid-1;
60         else l=mid+1;
61     }
62     return ans;
63 }
64 int main(){
65     int T;scanf("%d",&T);
66     while(T--){
67         scanf("%d%d",&n,&m);
68         build(1,1,n);
69         while(m--){
70             int op,x,y;
71             scanf("%d%d%d",&op,&x,&y);
72             if(op==1){
73                 x++;  //由于线段树叶子节点习惯从1~n开始存储,所以a++
74                 int cnt=query(1,1,n,x,n);  //查询这个区间的空瓶子数量
75                 if(cnt==0)printf("Can not put any one.\n");
76                 else{  //二分查找第一个空瓶子和最后一个空瓶子的下标
77                     int le=bin_search(x,1);
78                     int ri=bin_search(x,min(cnt,y));
79                     update(1,1,n,le,ri,0);
80                     printf("%d %d\n",le-1,ri-1);
81                 }
82             }
83             else{
84                 x++,y++;
85                 printf("%d\n",y-x+1-query(1,1,n,x,y));
86                 update(1,1,n,x,y,1);
87             }
88         }
89         printf("\n");
90     }
91     return 0;
92 }

2018-09-29

转载于:https://www.cnblogs.com/00isok/p/9727109.html

HDU 4614 Vases and Flowers 【线段树】+【二分】相关推荐

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

    题目链接 思路:线段树维护区间和,当k=1时,询问二分询问[x-(x~n-1)]找到最小位置,复杂度n*logn*logn卡过 #include<stdio.h> #include< ...

  2. hdu4614 Vases and Flowers 线段树+二分

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614 题意: 给你N个花瓶,编号是0  到 N - 1 ,初始状态花瓶是空的,每个花瓶最多插一朵花. ...

  3. hdu 4614 Vases and Flowers

    http://acm.hdu.edu.cn/showproblem.php?pid=4614 题意:有N个花瓶,标号为0-N-1,往每一个花瓶放一朵花,然后有M个操作,输入a,b,c,如果a==1表示 ...

  4. 牛客小白月赛28 E-会当凌绝顶,一览众山小 线段树+二分暴力模拟

    牛客小白月赛28 E-会当凌绝顶,一览众山小 线段树+二分暴力模拟 题意 思路 Code 传送门: https://ac.nowcoder.com/acm/contest/16081/E 题意 登山顺 ...

  5. HDU 1166 敌兵布阵(线段树:点更新,区间求和)

    HDU 1166 敌兵布阵(线段树:点更新,区间求和) http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意: 给你n个整数,然后给你多条命令,每条命令如 ...

  6. codeforces 609F Frogs and mosquitoes 线段树+二分+multiset

    http://codeforces.com/problemset/problem/609/F There are n frogs sitting on the coordinate axis Ox. ...

  7. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  8. 2019CCPC网络赛 1002 HDU 6703(权值线段树)

    2019CCPC网络赛 1002 HDU 6703(权值线段树) 思路:用权值线段树存题目给的数据后,2操作就是求权值线段树中大于等于k的部分中,靠近左端点的第一个大于r的值(这个求出来的只是原序列中 ...

  9. HDU 6070 Dirt Ratio(线段树、二分)

    http://acm.hdu.edu.cn/showproblem.php?pid=6070 题解 首先不难看出错误率是单调的,那么我们可以直接二分答案x,某个区间的错误率=区间数的种类cnt/区间长 ...

最新文章

  1. 关于mouseenter、mouseover、mouseout、mouseleave的理解
  2. Cisco学习笔记 CCNP-EIGRP
  3. lwip之数据收发流程_3
  4. 南工程计算机学院贴吧,【计算机工程学院答疑转帖】
  5. 栈的应用--括号匹配的检验
  6. 优秀的人都有一个共同点
  7. 如何轻松了解 Python 必学的 django 框架?
  8. 如何解决Mac上隐藏红色通知标记?技巧来啦
  9. 小程序的云服务器规格,小程序的云服务器规格
  10. 数据包络分析法(DEA) R实现
  11. 怎样培养数据分析的能力
  12. python 运行报错 Process finished with exit code -1073740791 (0xC0000409)
  13. 点是否在三角形内——C++实现
  14. php获取手机本地,PHP通过API获取手机号码归属地
  15. AWS之(2) RDS数据库新建
  16. 计算机屏幕一直闪,如何解决电脑显示器一直闪的问题
  17. 抖音蓝V如何认证,蓝V号与普通号的区别?
  18. ESP8266天猫精灵接入流程
  19. ArcGIS教程:分水岭的工作原理
  20. 装机春天时刻,盘点4月高性价比国产SSD

热门文章

  1. Android 之 布局训练
  2. epoll 或者 kqueue 的原理是什么?
  3. MySQL索引 专题
  4. puppet自动化运维之puppet的资源基础知识
  5. Asp.net Web.Config - 配置元素customErrors
  6. CentOS 7常用命令
  7. 随堂小测app冲刺(六)
  8. (POJ 3026) Borg Maze 最小生成树+bfs
  9. 最大连续子序列和-动态规划
  10. 【转】HTML5 本地存储五种方案