/*
hdu4614
本题刚开始想能不能记录该区间最前面开始的点,最后面的点,区间空的数量;但是病不行
然后线段树的本质是区间操作,所以!这题主要就是区间的空的全放满,只要定出区间的边界就好办了;
这里用二分查找的方法,现计算满足数量的区间的尾,因为头已经确定了,及时不放花也是确定的,只要靠数量定出尾就可以了;
然后就是区间修改了;
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX_N 50001
using namespace std;
int n,m,first,last,num,x;
struct tree
{
int l,r,fir,las,s,same,val;
}tr[MAX_N*];
void build(int rt,int l,int r)
{
tr[rt].l=l;tr[rt].r=r;
tr[rt].fir=l;
tr[rt].las=r;
tr[rt].s=;
tr[rt].val=r-l+;
if(l==r)
{
tr[rt].same=;
return ;
}
tr[rt].same=;
int mid=(l+r)/;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
}
void Pushup(int rt)
{
int l=rt<<,r=rt<<|;
if(tr[l].fir==)
tr[rt].fir=tr[r].fir;
else tr[rt].fir=tr[l].fir;
if(tr[r].las==)
tr[rt].las=tr[l].las;
else tr[rt].las=tr[r].las;
tr[rt].val=tr[r].val+tr[l].val; }
void Pushdown(int rt)
{
if(tr[rt].l==tr[rt].r)
return ;
int l=rt<<,r=rt<<|;
if(tr[rt].same)
{
if(tr[rt].s==)
{
tr[r].val=tr[l].val=;
tr[r].s=tr[l].s=;
tr[r].fir=tr[l].fir=;
tr[r].las=tr[l].las=;
tr[r].same=tr[l].same=;
tr[rt].same=;
}
else
{
tr[r].val=tr[r].r-tr[r].l+;
tr[l].val=tr[l].r-tr[l].l+;
tr[r].s=tr[l].s=;
tr[r].same=tr[l].same=;
tr[r].fir=tr[r].l;
tr[r].las=tr[r].r;
tr[l].fir=tr[l].l;
tr[l].las=tr[l].r;
tr[rt].same=;
}
}
}
void Update1(int rt,int l,int r)
{
if(x<=)
return ;
if(tr[rt].val==)
return ;//在二分查找定区间后,少了这一句所以一直tle
if(tr[rt].l==l&&tr[rt].val>)
{
if(first==)
first=tr[rt].fir;
if(tr[rt].val<=x)
{
if(last<tr[rt].las)
last=tr[rt].las;
x-=tr[rt].val;
tr[rt].same=;
tr[rt].s=;
tr[rt].val=;
tr[rt].fir=;
tr[rt].las=;
return ;
}
}
if(tr[rt].l==tr[rt].r)
return ;
Pushdown(rt);
int L=rt<<,R=rt<<|;
if(l<=tr[L].r)
{
if(r<=tr[L].r)
Update1(L,l,r);
else
Update1(L,l,tr[L].r);
}
if(r>=tr[R].l)
{
if(l>=tr[R].l)
Update1(R,l,r);
else
Update1(R,tr[R].l,r);
}
Pushup(rt);
}
void Update2(int rt,int l,int r)
{
if(tr[rt].l==l&&tr[rt].r==r)
{
num+=r-l+-tr[rt].val;
tr[rt].val=r-l+;
tr[rt].s=;
tr[rt].same=;
tr[rt].fir=l;
tr[rt].las=r;
return;
}
if(tr[rt].l==tr[rt].r)
return ;
Pushdown(rt);
int L=rt<<,R=rt<<|;
if(l<=tr[L].r)
{
if(r<=tr[L].r)
Update2(L,l,r);
else
Update2(L,l,tr[L].r);
}
if(r>=tr[R].l)
{
if(l>=tr[R].l)
Update2(R,l,r);
else
Update2(R,tr[R].l,r);
}
Pushup(rt);
}
int sum(int rt,int l,int r)
{
if(tr[rt].l==l&&tr[rt].r==r)
{
return tr[rt].val;
}
int ans=;
Pushdown(rt);//因为只是查询,所以区间整体并没有变,就没有必要pushup了;
int L=rt<<,R=rt<<|;
if(l<=tr[L].r)
{
if(r<=tr[L].r)
ans+= sum(L,l,r);
else
ans+= sum(L,l,tr[L].r);
}
if(r>=tr[R].l)
{
if(l>=tr[R].l)
ans+= sum(R,l,r);
else
ans+= sum(R,tr[R].l,r);
}
return ans;
}
int bisearch(int a,int f)
{
if(sum(,a,n)==)
return -;
if(sum(,a,n)<f)//此处的等于号的问题;
return n;
int l=a,r=n;
int ans=a;
while(l<=r)
{
int mid=(l+r)/;
if(sum(,a,mid)>=f)//以及此处的等于号;
{
ans=mid;//这里ans的取值;
r=mid-;
}
else l=mid+;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
build(,,n);
for(int i=;i<m;i++)
{
int ty,z,y;
scanf("%d%d%d",&ty,&z,&y);
if(ty==)
{
int t=bisearch(z+,y);
if(t!=-)
{
x=y;
first=;
last=;
Update1(,z+,t);
printf("%d %d\n",first-,last-);
}
else
printf("Can not put any one.\n");
}
else
{
num=;
Update2(,z+,y+);
printf("%d\n",num);
}
}
printf("\n");
}
return ;
}

kb-07线段树-12--二分查找区间边界的更多相关文章

  1. HDU 4614 线段树+二分查找

    Vases and Flowers 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4614 Problem Description Alice is s ...

  2. K-th Number 线段树(归并树)+二分查找

    K-th Number 题意:给定一个包含n个不同数的数列a1, a2, ..., an 和m个三元组表示的查询.对于每个查询(i, j, k), 输出ai, ai+1, ... ,aj的升序排列中第 ...

  3. poj 2892---Tunnel Warfare(线段树单点更新、区间合并)

    题目链接 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensiv ...

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

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

  5. BZOJ5142: [Usaco2017 Dec]Haybale Feast 线段树或二分答案

    Description Farmer John is preparing a delicious meal for his cows! In his barn, he has NN haybales ...

  6. POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)

    A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...

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

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

  8. HDU 3577 Fast Arrangement ( 线段树 成段更新 区间最值 区间最大覆盖次数 )

    线段树成段更新+区间最值. 注意某人的乘车区间是[a, b-1],因为他在b站就下车了. #include <cstdio> #include <cstring> #inclu ...

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

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

随机推荐

  1. Ubuntu系统Apache 2部署SSL证书

    几天前用Apache 2部署了一个静态网页,但通过域名访问时Google提示“不安全”,经了解,原来是缺少证书. 什么是SSL证书? SSL 是指安全套接字层,简而言之,它是一项标准技术,可确保互联网 ...

  2. 使用xcode 8 调试ios10

    这几天更新了ios10,发现真机不能调试,弹出几个错,表示没有证书.用ios9的真机能调试, 真他么坑,总结一下解决方法. 在BuildSetting 的Signing中Code Signing Id ...

  3. 利用SignalR实现实时聊天

    2018/10/10:博主第一次写原创博文而且还是关于C#的(博主是从前端转过来的),菜鸟一枚,如果有什么写的不对,理解错误,还望各位轻喷.,从SignalR开始! 首先先介绍一下关于SignalR的 ...

  4. 测试 code style

    c++ #include <iostream> int main(int argc, char *argv[]) { /* An annoying "Hello World&qu ...

  5. PCA检测人脸的简单示例_matlab实现

    PCA检测人脸的简单示例,matlab R2009b上实现训练:训练用的20副人脸: %训练%Lx=X'*Xclear;clc;train_path='..\Data\TrainingSet\';ph ...

  6. 洛谷 P5016 龙虎斗

    输入兵营总数.兵营人数.以m分界. 然后输入s1个兵到了p1兵营. 最终我们要求的是把s2个兵放到哪个兵营使龙虎双方气势差距最小. 第一要把每个兵营的气势算出来,并且加到它所属的阵营里(<m是龙 ...

  7. RabbitMQ学习(二):Java使用RabbitMQ要点知识

    转  https://blog.csdn.net/leixiaotao_java/article/details/78924863 1.maven依赖 <dependency> <g ...

  8. k8s Pod的自动水平伸缩(HPA)

    我们知道,当访问量或资源需求过高时,使用:kubectl scale命令可以实现对pod的快速伸缩功能 但是我们平时工作中我们并不能提前预知访问量有多少,资源需求多少. 这就很麻烦了,总不能为了需求总 ...

  9. 如何使用postman做接口测试

    1.get请求传参 只要是get请求都可以在浏览器中直接发: 在访问地址后面拼  ?key=value&key=value 例如: 在浏览器中直接输入访问地址,后面直接拼需要传给服务器的参数 ...

  10. setup/hold 分析

    分析说明:D2:目的寄存器:D1:源寄存器: edge2:下一个时钟上升沿:edge1:当前时钟上升沿:edge0:当前时钟上升沿的前一个时钟沿:如下图: 建立时间:触发器D2(数据要到达目的的地方) ...