hdu4614 线段树+二分 插花
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
现在要你插花,有n个花瓶,m次操作,初始花瓶中无花,操作有两种方式
操作1:1 a b,从编号为a的花瓶开始插花,共插b朵花,花只能插到无花的花瓶中,如果最后插不完b朵花,剩下的花舍弃掉
操作2:1 a b,把从编号a到编号b的所有花瓶里的花全部清理掉
对于操作1,需要输出开始插花的瓶子编号,和最后插花的瓶子编号
对于操作2,需要输出在a~b中总共清理了多少个花瓶中的花
题解:线段树+二分,分析一下这道题,如果是情理,那是十分容易的,只需要lazy,tag就可以了,但是如何去找区间第一个可以插的位置呢,
线段树可以记录该位置里的有多少个空位置,那么我们可以二分,来查找判断是多了,还是少了,这样就可以了,时间复杂度就控制了
下来,然后整个区间填满,什么区间?就是第一支花和最后一枝花那个区间,hh。
#include<iostream>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
using namespace std;
struct node
{
int l,r;
int tag;//如果为-1则为初始状态,如果为0意思将子区间内的花清空,为1为插满花
int v;//记录区间内插了多少花
}t[*];
int n;
void Build(int l,int r,int k)
{
t[k].l=l;
t[k].r=r;
t[k].v=;
t[k].tag=-;
if(l==r)
return;
int mid=(l+r)/;
Build(l,mid,k*);
Build(mid+,r,k*+);
}
void pushdown(int k)//向下传递状态
{
t[k*].tag=t[k*+].tag=t[k].tag;
t[k*].v=t[k].tag*(t[k*].r-t[k*].l+);
t[k*+].v=t[k].tag*(t[k*+].r-t[k*+].l+);
t[k].tag=-;
}
void update(int l,int r,int v,int k)
{
if(t[k].l==l&&t[k].r==r)
{
t[k].tag=v;
t[k].v=v*(r-l+);//插满或者清空
return;
}
if(t[k].tag!=-)//要传递状态
pushdown(k);
int mid=(t[k].l+t[k].r)/;
if(r<=mid)
update(l,r,v,k*);
else if(l>mid)
update(l,r,v,k*+);
else
{
update(l,mid,v,k*);
update(mid+,r,v,k*+);
}
t[k].v=t[k*].v+t[k*+].v;//向上传递区间信息
}
int query(int l,int r,int k)//查询区间内插花的数目
{
if(t[k].l==l&&t[k].r==r)
{
return t[k].v;
}
if(t[k].tag!=-)//同样lazy tag
pushdown(k);
int mid=(t[k].l+t[k].r)/;
if(r<=mid)
return query(l,r,k*);
else if(l>mid)
return query(l,r,k*+);
else
{
return query(l,mid,k*)+query(mid+,r,k*+);
}
t[k].v=t[k*].v+t[k*+].v;
}
int dive(int s,int num)//二分查找,第一个为开始的位置,第二个参数为要插多少个
{
int temp=query(s,n,);
if(temp==n-s+)//如果一个都不能插
return -;
if(n-s+-temp<num)//如果空位小于要插的数目,改下要插的数目
num=n-s+-temp;
int l=s;
int r=n;
int mid,d;
int f=-;
while(r>=l)//二分
{
mid=(l+r)/;
d=mid-s+-query(s,mid,);//d为从s到mid的空位数目
if(d>num)
{
r=mid-;
}
else if(d<num)
l=mid+;
else//如果空位的数目正好要一个个减
{
f=mid;//为了保存第一个能够满足该数目空位的位置
r=mid-;
}
}
return f;
}
int main()
{
int i,j,test,x,y,d,m;
scanf("%d",&test);
while(test--)
{
scanf("%d%d",&n,&m);
n--;
Build(,n,);
for(i=;i<m;i++)
{
scanf("%d%d%d",&d,&x,&y);
if(d==)
{
int temp=dive(x,);//查找插的第一个位置
if(temp==-)
{
printf("Can not put any one.\n");
}
else
{
int en=dive(x,y);//查找插的第二个位置
printf("%d %d\n",temp,en);
update(temp,en,,);//更新插满区间
}
}
else
{
printf("%d\n",query(x,y,));
update(x,y,,);//清空区间
}
}
printf("\n");
}
return ;
}
hdu4614 线段树+二分 插花的更多相关文章
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
- luogu4422 [COCI2017-2018#1] Deda[线段树二分]
讨论帖:线段树二分的题..我还考场切过..白学 这题我一年前的模拟赛考场还切过,现在就不会了..好菜啊. 显然直接线段树拆成$\log n$个区间,然后每个区间在进行线段树二分即可. UPD:复杂度分 ...
- bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...
- [BZOJ 2653] middle(可持久化线段树+二分答案)
[BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...
- Educational Codeforces Round 64 (Rated for Div. 2) (线段树二分)
题目:http://codeforces.com/contest/1156/problem/E 题意:给你1-n n个数,然后求有多少个区间[l,r] 满足 a[l]+a[r]=max([l, ...
- 洛谷$P2824\ [HEOI2016/TJOI2016]$ 排序 线段树+二分
正解:线段树+二分 解题报告: 传送门$QwQ$ 昂着题好神噢我$jio$得$QwQQQQQ$,,, 开始看到长得很像之前考试题的亚子,,,然后仔细康康发现不一样昂$kk$,就这里范围是$[1,n]$ ...
- 2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串)
2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串) https://www.luogu.com.cn/problem/P2824 题意: 在 20 ...
随机推荐
- switch_to 家族
selenium做自动化的过程中,经常会遇到alert.frame和新的window,这是经常是switch_to家族大展拳脚的时候,先看看switch_to家族的成员: alert --返回浏览器的 ...
- 学生管理系统开发代码分析笔记:jsp+java bean+servlet技术
1 序言 学习java web的时候很渴望有一份完整的项目给我阅读,而网上的大部分项目拿过来都无法直接用,好不容易找到了一个学生管理系统也是漏洞百出.在此,我将边修改边学习这份代码,并且加上完全的注释 ...
- 在tomcat7中启用HTTPS的详细配置
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt385 最简单的方法,直接用java里的keytool工具生成一个keysto ...
- Spring 对缓存的抽象
Cache vs. Buffer A buffer is used traditionally as an intermediate temporary store for data between ...
- 学会Git
学会Git 目录 一.版本控制概要 1.1.什么是版本控制 1.2.常用术语 1.3.常见的版本控制器 1.4.版本控制分类 1.4.1.本地版本控制 1.4.2.集中版本控制 1.4.3.分布式 ...
- 九度OJ 1016 火星A + B 未AC版,整型存储不下
#include <iostream> #include <string.h> #include <sstream> #include <math.h> ...
- 【1414软工助教】团队作业7——Alpha冲刺之事后诸葛亮 得分榜
题目 团队作业7--Alpha冲刺之事后诸葛亮 往期成绩 个人作业1:四则运算控制台 结对项目1:GUI 个人作业2:案例分析 结对项目2:单元测试 团队作业1:团队展示 团队作业2:需求分析& ...
- 团队作业4——第一次项目冲刺 tHiRd DaY
项目冲刺--Triple Kill 小编又来了,好困呐,上了一天的课还要写博客,为什么写博客的一直是我呢..一点乐子都没有*-* 但是我还是得写啊[我也很无奈啊],那就让我给大家找点乐子吧 天霸动霸. ...
- 201521123003《Java程序设计》第8周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结 我们利用Sca ...
- 201521123087 《Java程序设计》第3周学习总结
1.本周学习总结 2. 书面作业 代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; publ ...