HDU 4614 Vases and Flowers(线段树+二分)
Vases and Flowers
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 3220 Accepted Submission(s): 1273
For each test case, the first line contains two integers N(1 < N < 50001) and M(1 < M < 50001). N is the number of vases, and M is the operations of Alice. Each of the next M lines contains three integers. The first integer of one line is K(1 or 2). If K is 1, then two integers A and F follow. It means Alice receive F flowers and try to put a flower in the vase A first. If K is 2, then two integers A and B follow. It means the owner would like to clean the vases numbered from A to B(A <= B).
Output one blank line after each test case.
题目链接:HDU 4614
题意就是给一个编号为0~N-1的花瓶,给一系列操作:1、从起始点S开始插入F朵花,插入时连续地从左到右扫描过去若花瓶有空且花没用完就一定要插到花瓶里,最后要么花用完了要么没位置可以放置了;2、清空编号从L到R花瓶。
这题第二问明显可以用线段树做,而且由于前缀和的缘故,花的前缀和数量在编号序列上具有单调性,因此第一问可以用二分做,但是二分开头简单,二分结尾就比较恶心,调试了很久,仔细考虑可以发现会有这样一个容易错误的地方:若从头到尾空位比花少,则终点为第一个达到最大空位的位置,而不是一直到结尾,因此要仅当当前位置的前缀空位和等于最大空位数的时候才记录终点T。如果二分结尾不正确估计第二组样例会对不上
代码:
- #include <stdio.h>
- #include <bits/stdc++.h>
- using namespace std;
- #define INF 0x3f3f3f3f
- #define LC(x) (x<<1)
- #define RC(x) ((x<<1)+1)
- #define MID(x,y) ((x+y)>>1)
- #define CLR(arr,val) memset(arr,val,sizeof(arr))
- #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
- typedef pair<int, int> pii;
- typedef long long LL;
- const double PI = acos(-1.0);
- const int N = 50010;
- struct seg
- {
- int l, mid, r;
- int sum, add;
- inline int len()
- {
- return r - l + 1;
- }
- };
- seg T[N << 2];
- inline void pushup(int k)
- {
- T[k].sum = T[LC(k)].sum + T[RC(k)].sum;
- }
- inline void pushdown(int k)
- {
- if (!T[k].add)
- return ;
- T[LC(k)].add = T[k].add;
- T[RC(k)].add = T[k].add;
- T[LC(k)].sum = (T[k].add == 1) * T[LC(k)].len();
- T[RC(k)].sum = (T[k].add == 1) * T[RC(k)].len();
- T[k].add = 0;
- }
- void build(int k, int l, int r)
- {
- T[k].l = l;
- T[k].r = r;
- T[k].mid = MID(l, r);
- T[k].sum = T[k].add = 0;
- if (l == r)
- return ;
- else
- {
- build(LC(k), l, T[k].mid);
- build(RC(k), T[k].mid + 1, r);
- }
- }
- void update(int k, int l, int r, int flag)
- {
- if (l <= T[k].l && T[k].r <= r)
- {
- T[k].add = flag;
- T[k].sum = (flag == 1 ? T[k].len() : 0);
- }
- else
- {
- pushdown(k);
- if (l <= T[k].mid)
- update(LC(k), l, r, flag);
- if (r > T[k].mid)
- update(RC(k), l, r, flag);
- pushup(k);
- }
- }
- int query(int k, int l, int r)
- {
- if (l <= T[k].l && T[k].r <= r)
- return T[k].sum;
- else
- {
- pushdown(k);
- if (r <= T[k].mid)
- return query(LC(k), l, r);
- else if (l > T[k].mid)
- return query(RC(k), l, r);
- else
- return query(LC(k), l, T[k].mid) + query(RC(k), T[k].mid + 1, r);
- }
- }
- int main(void)
- {
- int tcase, n, m, ops, l, r;
- scanf("%d", &tcase);
- while (tcase--)
- {
- scanf("%d%d", &n, &m);
- build(1, 0, n - 1);
- while (m--)
- {
- scanf("%d%d%d", &ops, &l, &r);
- if (ops == 2)
- {
- int discard = query(1, l, r);
- update(1, l, r, -1);
- printf("%d\n", discard);
- }
- else if (ops == 1)
- {
- int S = -1; //二分找到第一个为空的点
- int L = l, need = r, R = n - 1;
- while (L <= R)
- {
- int mid = (L + R) >> 1;
- if (query(1, l, mid) < mid - l + 1)
- {
- S = mid;
- R = mid - 1;
- }
- else
- L = mid + 1;
- }
- if (S == -1)//连开头位置都不存在,肯定位置全满了
- puts("Can not put any one.");
- else
- {
- int maxmvacnt = (n - 1 - S + 1) - query(1, S, n - 1);//用实际上最大的空位数而不是花朵数去二分
- need = min<int>(need, maxmvacnt);
- int T = -1;
- int L = S, R = n - 1;
- while (L <= R)
- {
- int mid = (L + R) >> 1;
- int vacant = mid - S + 1 - query(1, S, mid);
- if (vacant < need)
- L = mid + 1;
- else if (vacant == need) //此处与普通二分有一点不同
- {
- T = mid;
- R = mid - 1;
- }
- else
- R = mid - 1;
- }
- printf("%d %d\n", S, T);
- update(1, S, T, 1);
- }
- }
- }
- putchar('\n');
- }
- return 0;
- }
HDU 4614 Vases and Flowers(线段树+二分)的更多相关文章
- HDU 4614 Vases and Flowers(线段树+二分)
题目链接 比赛的时候一直想用树状数组,但是树状数组区间更新之后,功能有局限性.线段树中的lz标记很强大,这个题的题意也挺纠结的. k = 1时,从a开始,插b个花,输出第一个插的位置,最后一个的位置, ...
- hdu 4614 Vases and Flowers 线段树
题目链接 一共n个盒子, 两种操作, 第一种是给出两个数x, y, 从第x个盒子开始放y朵花, 一个盒子只能放一朵, 如果某个盒子已经有了, 那么就跳过这个盒子放下面的盒子. 直到花放完了或者到了最后 ...
- hdu4614 Vases and Flowers 线段树+二分
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614 题意: 给你N个花瓶,编号是0 到 N - 1 ,初始状态花瓶是空的,每个花瓶最多插一朵花. ...
- HDU 4614 Vases and Flowers(二分+线段树区间查询修改)
描述Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to ...
- HDU 4614 Vases and Flowers 【线段树】+【二分】
<题目链接> 题目大意: 有n个花瓶,每个花瓶中只能放一朵花.两种操作,一种是从A开始放F朵花,如果有的花瓶中已经有花则跳过这个花瓶,往下一个花瓶放:第二种是将区间[A,B]之间花瓶中的花 ...
- HDU 4614 Vases and Flowers (2013多校2 1004 线段树)
Vases and Flowers Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others ...
- HDU 4614 Vases and Flowers(线段树+记录区间始末点或乱搞)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614 题目大意:有n个空花瓶,有两种操作: 操作①:给出两个数字A,B,表示从第A个花瓶开始插花,插B ...
- HDU 4614 Vases and Flowers (2013多校第二场线段树)
题意摘自:http://blog.csdn.net/kdqzzxxcc/article/details/9474169 ORZZ 题意:给你N个花瓶,编号是0 到 N - 1 ,初始状态花瓶是空的,每 ...
- hdu 4614 Vases and Flowers(线段树:成段更新)
线段树裸题.自己写复杂了,准确说是没想清楚就敲了. 先是建点为已插花之和,其实和未插花是一个道理,可是开始是小绕,后来滚雪球了,跪了. 重新建图,分解询问1为:找出真正插画的开始点和终止点,做成段更新 ...
随机推荐
- 2dsphere索引
概念:球面地理位置索引 创建方式: db.collection.ensureIndex({w:'2dsphere'}) wdspere中,位置的表示方式不再是简单的经度,纬度,数组,而是变成一种复杂的 ...
- Java 发送 Http请求工具类
HttpClient.java package util; import java.io.BufferedReader; import java.io.IOException; import java ...
- centos 7 虚拟机启用网卡
1.vi /etc/sysconfig/network-scripts/ifcfg-enp0s3 2.编辑默认网卡配置文件,将ONBOOT由no改为yes,编辑完成后,按ESC回至命令模板,输入&qu ...
- js清空表单数据的方式(遍历+reset)
方法1:遍历页面元素 /* 清空FORM表单内容 id:表单ID*/ function ClearForm(id) { var objId = document.getElementById(id); ...
- 问题006:为什么用java.exe执行编译的类文件的时候,不这样写java Welcome.class
为什么用java.exe执行编译的类文件的时候,不这样写java Welcome.class 是因为java虚拟机调用Welcome的时候,已经替我们增减了.class,如果你还要写java Welc ...
- SpringMVC 多视图解析器 跳转问题
在SpringMVC的配置文件中加入以下配置: <!-- 下面红色的配置必须要在--> <mvc:default-servlet-handler /> <bean id ...
- 项目10.2-企业级自动化运维工具---puppet详解
1.认识puppet 1.1 引入 puppet是什么,咱们先不用专业的名词解释它,咱们先描述一些工作场景,看明白这些工作场景,自然会知道puppet是什么. (1)场景一: 管理员想要在100台服务 ...
- 以太坊国内节点大全(ropsten)
admin.addPeer('enode://2d1e1f1242c3b54ea56046f74f15943f47ab410e3c0b82bffb501793ebb19e147f8f0e63d01c2 ...
- linux 基本指令 归类
今天 我们来学习一下 最最基础的linux 指令,在我看来 linux的操作就是 增 删 改 查 这四个字. 1 查询 操作用户 woami 2查询登录用户 who am i 2 pwd //查询当前 ...
- Android stadio litepal
今天看到技术交流群里有人招聘Android,要求会litepal. 我立马百度了下.嗯,我的学习技术的精神,是值得称赞的. litepal就是操作数据库的一个框架.git地址: https://git ...