Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N-1. When she receive some flowers, she will try to put them in the vases, one flower in one vase. She randomly choose the vase A and try to put a flower in the vase. If the there is no flower in the vase, she will put a flower in it, otherwise she skip this vase. And then she will try put in the vase A+1, A+2, ..., N-1, until there is no flower left or she has tried the vase N-1. The left flowers will be discarded. Of course, sometimes she will clean the vases. Because there are too many vases, she randomly choose to clean the vases numbered from A to B(A <= B). The flowers in the cleaned vases will be discarded.

Input

  The first line contains an integer T, indicating the number of test cases. 

  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

  For each operation of which K is 1, output the position of the vase in which Alice put the first flower and last one, separated by a blank. If she can not put any one, then output 'Can not put any one.'. For each operation of which K is 2, output the number of discarded flowers. 

   Output one blank line after each test case.

Sample Input

2
10 5
1 3 5
2 4 5
1 1 8
2 3 6
1 8 8
10 6
1 2 5
2 3 4
1 0 8
2 2 5
1 4 4
1 2 3

Sample Output

[pre]3 7
2
1 9
4
Can not put any one. 2 6
2
0 9
4
4 5
2 3 [/pre]

要和二分结合一下 线段树方面没有什么特别的

但是一时想不到要和二分结合

查询就是查区间的和 更新也就是全变0或全变1 关键就是怎么找到最开始可以插花的位子和最后一个位子

这里就需要二分了

先二分找到可以插花的位子 pos

再二分找到可以插花的最远的位子ans 这个位子可能已经有花了 反正就是pos到ans可以把花都插进去

最后二分找到实际的最后插花的位子 realans


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#define inf 1e18
using namespace std; const int maxn = 50005;
int flower[maxn << 2];
int same[maxn << 2];
int m, n; void pushup(int rt)
{
flower[rt] = flower[rt << 1] + flower[rt<<1|1];
//same[rt] = same[rt<<1] && same[rt<<1|1];
} void build(int l, int r, int rt)
{
flower[rt] = 0;
same[rt] = 0;
if(l == r) return;
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
pushup(rt);
} void pushdown(int l, int r, int rt)
{
if(same[rt]){
int m = (l + r) / 2;
same[rt<<1] = same[rt<<1|1] = same[rt];
flower[rt<<1] = (m - l + 1) * same[rt];
flower[rt<<1|1] = (r - m) * same[rt];
if(same[rt] == -1){
flower[rt<<1] = flower[rt<<1|1] = 0;
}
same[rt] = 0;
} } void update(int L, int R, int x, int l, int r, int rt)
{
if(l >= L && r <= R){
if(x == 1){
flower[rt] = r - l + 1;
same[rt] = true;
}
else{
flower[rt] = 0;
same[rt] = -1;
}
return;
}
pushdown(l, r, rt);
int m = (l + r) / 2;
if(L <= m) update(L, R, x, l, m, rt<<1);
if(R > m) update(L, R, x, m + 1, r, rt<<1|1);
pushup(rt);
} int query(int L, int R, int l, int r, int rt)
{
if(L <= l && R >= r){
return flower[rt];
}
pushdown(l, r, rt);
int m = (l + r) / 2, ans = 0;
if(L <= m) ans += query(L, R, l, m, rt<<1);
if(R > m) ans += query(L, R, m + 1, r, rt<<1|1);
pushup(rt);
return ans;
} int main()
{
int t;
cin>>t;
while(t--){
scanf("%d%d", &n, &m);
build(1, n, 1);
while(m--){
int l, r, op;
scanf("%d%d%d", &op, &l, &r);
l++;r++;
if(op == 1){
r--;
int left = l, right = n, pos = -1;
while(right - left >= 0){//找第一个可插花点
int mid = (right + left) / 2;
if(query(l, mid, 1, n, 1) == mid - l + 1){
left = mid + 1;
}
else{
right = mid - 1;
pos = mid;
}
}
if(pos == -1)
printf("Can not put any one.\n");
else{
int ans = -1;
left = pos;
right = n;
while(right - left >= 0){//找最远可插花位子 得到的ans可能原来已经被插上花
int mid = (left + right) / 2;
if(mid - pos + 1 - query(pos, mid, 1, n, 1) <= r){
left = mid + 1;
ans = mid;
}
else{
right = mid - 1;
}
}
int realans = -1;
left = pos;
right = ans;
while(right - left >= 0){//找到实际插最后一朵花的位子,可能花没被插完
//要在pos到ans中找到最远的空位
int mid = (left + right) / 2;
if(ans - mid + 1 - query(mid, ans, 1, n, 1) == 0){
right = mid - 1;
realans = mid;
}
else left = mid + 1;
}
if(realans == -1){
printf("%d %d\n", pos - 1, ans - 1);
}
else{
printf("%d %d\n", pos - 1, realans - 2);
}
update(pos, ans, 1, 1, n, 1);
}
}
if(op == 2){
printf("%d\n", query(l, r, 1, n, 1));
update(l, r, -1, 1, n, 1);
}
}
printf("\n");
}
return 0;
}

hdu4614 Vases and Flowers【线段树】【二分】的更多相关文章

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

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

  2. hdu4614 Vases and Flowers 线段树

    Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...

  3. HDU-4614 Vases and Flowers 线段树区间更新

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614 线段树保存区间是否被覆盖以及区间的和即可,在询问的时候在线段树上二分查找就可以了...代码写得比 ...

  4. HDU 4614 Vases and Flowers(线段树+二分)

    题目链接 比赛的时候一直想用树状数组,但是树状数组区间更新之后,功能有局限性.线段树中的lz标记很强大,这个题的题意也挺纠结的. k = 1时,从a开始,插b个花,输出第一个插的位置,最后一个的位置, ...

  5. hdu 4614 Vases and Flowers 线段树

    题目链接 一共n个盒子, 两种操作, 第一种是给出两个数x, y, 从第x个盒子开始放y朵花, 一个盒子只能放一朵, 如果某个盒子已经有了, 那么就跳过这个盒子放下面的盒子. 直到花放完了或者到了最后 ...

  6. hdu4614 线段树+二分 插花

    Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...

  7. Codeforces Gym 100803G Flipping Parentheses 线段树+二分

    Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...

  8. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  9. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

  10. luogu4422 [COCI2017-2018#1] Deda[线段树二分]

    讨论帖:线段树二分的题..我还考场切过..白学 这题我一年前的模拟赛考场还切过,现在就不会了..好菜啊. 显然直接线段树拆成$\log n$个区间,然后每个区间在进行线段树二分即可. UPD:复杂度分 ...

随机推荐

  1. Linux命令缩写的全称

    [目录|文件] ls : list(列出目录内容) pwd : print work directory(打印当前目录,现示当前工作目录的绝对路径) cd : change directory(改变目 ...

  2. phonegap入门–1 Android 开发环境搭建

    一.JDK 安装JDK,安装包中包含了JDK和JRE两部分,建议将它们安装在同一个盘符下面. 配置环境变量: 1.右键点击我的电脑,选择属性,点击高级选项卡,选择环境变量. 2.找到Path变量名(无 ...

  3. Floyd算法解说

    開始知道Floyd算法是在<大话数据结构>这本书的无向带权图求最短路径看到的, 可是第一次没怎么看懂,所以就不看了,后来又看了两遍还是没明确,我以为是我理解能力有问题 后来从百度百科上看了 ...

  4. 02-centOS6.7安装

    CentOS6.5在VMware10中安装 1.启动VMware的画面 2.点击File--->New Virtual Machine 创建一台新虚拟机 3.在弹出框中选择典型安装 4.选择I ...

  5. Spring整合quartz2.2.3总结,quartz动态定时任务,Quartz定时任务集群配置

    Spring整合quartz2.2.3总结,quartz动态定时任务,Quartz定时任务集群配置 >>>>>>>>>>>>&g ...

  6. Splash evaljs() 方法

    evaljs() 方法可以执行 JavaScript 代码并返回最后一条 JavaScript 语句的返回结果 function main(splash, args) splash:go(" ...

  7. map 集合的遍历

    List<Map<String,Object>> autoReplyList= wechatService.queryAutoReplyByOrg(orgId); for(Ma ...

  8. Elasticsearch 版本控制

    悲观并发控制(Pessimistic concurrency control) 这在关系型数据库中被广泛的使用,假设冲突的更改经常发生,为了解决冲突我们把访问区块化.典型的例子是在读一行数据前锁定这行 ...

  9. 树莓派3安装opencv2程序无法运行

    在raspberry pi3 上安装opencv3已测试,没有问题,而opencv2报错如下: Xlib: extension "RANDR" missing on display ...

  10. Qt编写数据库通用翻页demo(开源)

    在Qt与数据库结合编程的过程中,记录一多,基本上都需要用到翻页查看记录,翻页有个好处就是可以减轻显示数据的表格的压力,不需要一次性将数据库表的记录全部显示,也基本上没有谁在一页上需要一次性显示所有记录 ...