题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614

题意:

给你N个花瓶,编号是0  到 N - 1 ,初始状态花瓶是空的,每个花瓶最多插一朵花。

然后有2个操作。

操作1,a b c ,往在a位置后面(包括a)插b朵花,输出插入的首位置和末位置。

操作2,a b ,输出区间[a , b ]范围内的花的数量,然后全部清空。

很显然这是一道线段树。区间更新,区间求和,

操作2,很显然就是线段树的区间求和,求出[a , b]范围内的花朵的数量,区间更新,将整个区间全部变成0。

操作1,这里我们首先需要找出他的首位置和末位置,所以需要二分他的位置。

首先我们二分他的首位置, l = a , r = n ,在这个区间内二分,找出第一个0的位置,那就是该操作的首位置pos1。

然后再二分他的末位置,l = pos1 , r = n ,找到第b个0,就是该操作的末位置pos2,然后区间更新[pos1 ,pos2]全部置为1

我最初主要是对二分不熟悉,做了几道二分的题目后再做这道题就很快了。。。。

很裸的一道线段树了,一定要用lazy思想设置flag标记位,不能更新到低,否则会超时的。。。。

代码:

 #include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define maxn 50010
int n,m;
class node
{
public:
int l;
int r;
int sum;
int flag;
};
node segTree[maxn*];
void Build(int num, int l, int r)
{
segTree[num].l=l;
segTree[num].r=r;
segTree[num].sum=;
segTree[num].flag=;
if(l==r) return;
int mid=(l+r)/;
Build(num*,l,mid);
Build(num*+,mid+,r);
}
int query(int num, int l, int r)
{
if(segTree[num].l ==l && segTree[num].r==r)
{
return segTree[num].sum;
}
int mid=(segTree[num].l + segTree[num].r)/;
if(segTree[num].flag==)
{
segTree[num*].sum=(segTree[num*].r - segTree[num*].l +);
segTree[num*+].sum=(segTree[num*+].r- segTree[num*+].l +);
segTree[num*].flag=;
segTree[num*+].flag=;
segTree[num].flag=;
}
if(segTree[num].flag ==-)
{
segTree[num*].sum=segTree[num*+].sum=;
segTree[num*].flag=segTree[num*+].flag=-;
segTree[num].flag=;
}
if(r <=mid) return query(num*,l,r);
else if(l >mid ) return query(num*+,l,r);
else
{
return query(num*,l,mid)+query(num*+,mid+,r);
}
}
void Update1(int num,int l, int r)
{
if(segTree[num].flag==) return;
if(segTree[num].l ==l && segTree[num].r==r)
{
segTree[num].sum=r-l+;
segTree[num].flag=;
return ;
}
int mid=(segTree[num].l + segTree[num].r)/;
if(segTree[num].flag==-)
{
segTree[num*].sum=segTree[num*+].sum=;
segTree[num*].flag=segTree[num*+].flag=-;
segTree[num].flag=;
}
if(r<=mid) Update1(num*,l,r);
else if(l>mid) Update1(num*+,l,r);
else
{
Update1(num*,l,mid);
Update1(num*+,mid+,r);
}
segTree[num].sum=segTree[num*].sum+segTree[num*+].sum;
}
void Update2(int num,int l,int r)
{
if(segTree[num].flag == -) return ;
if(segTree[num].l == l && segTree[num].r ==r)
{
segTree[num].flag=-;
segTree[num].sum=;
return ;
}
int mid=(segTree[num].l +segTree[num].r)/;
if(segTree[num].flag==)
{
segTree[num*].sum=(segTree[num*].r -segTree[num*].l +);
segTree[num*+].sum=(segTree[num*+].r -segTree[num*+].l +);
segTree[num*].flag=;
segTree[num*+].flag=;
segTree[num].flag=;
}
if(r<=mid) Update2( num*,l,r);
else if(l>mid) Update2(num*+,l,r);
else
{
Update2(num*,l,mid);
Update2(num*+,mid+,r);
}
segTree[num].sum=segTree[num*].sum+segTree[num*+].sum;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int k;
int A,F,B;
scanf("%d%d",&n,&m);
Build(,,n);
while(m--)
{
scanf("%d",&k);
if(k==)
{
scanf("%d%d",&A,&F);
A++;
int tol=n-A+-query(,A,n);
if(tol==)
{
cout<<"Can not put any one."<<endl;
continue;
} if(tol<F) F=tol;
int l=A;
int r=n;
int mid;
int pos1=n+,pos2=n+;
while(l<=r)
{
mid=(l+r)/;
int tol=mid-A+-query(,A,mid);
if(tol>=) pos1=min(pos1,mid),r=mid-;
else l=mid+;
} l=pos1;
r=n;
while(l<=r)
{
mid=(l+r)/;
int tol=mid-pos1+-query(,pos1,mid);
if(tol>=F) pos2=min(pos2,mid),r=mid-;
else l=mid+;
}
cout<<pos1-<<" "<<pos2-<<endl;
Update1(,pos1,pos2);
}
else
{
scanf("%d%d",&A,&B);
A++;B++;
int tol=query(,A,B);
cout<<tol<<endl;
Update2(,A,B);
} }
cout<<endl;
}
return ;
}

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

  1. hdu4614 Vases and Flowers 线段树

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

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

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

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

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

  4. hdu 4614 Vases and Flowers 线段树

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

  5. hdu4614 线段树+二分 插花

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

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

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

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

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

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

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

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

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

随机推荐

  1. java Servlet接口及应用(转)

    基本类和接口 一.javax.servlet.Servlet接口 servlet抽象集是javax.servlet.Servlet接口,它规定了必须由Servlet类实现由servlet引擎识别和管理 ...

  2. python之字符串

    字符串与文本操作 字符串: Python 2和Python 3最大的差别就在于字符串 Python 2中字符串是byte的有序序列 Python 3中字符串是unicode的有序序列 字符串是不可变的 ...

  3. 查找及修改日程管理系统中的bug

    1.Java没有分包都糅合在一起 2.在登录界面,没有输入账号密码,点击登录按钮时程序会崩溃,需要给给用户名和密码添加Toast (注:由于程序没有运行出来,所以是搭档孙刘兰的截图) 3.Regist ...

  4. 以正确的姿势实现一棵JavaScript菜单树

    菜单树是常见的前端特效, 一般长下面这样 还有各种形态的变种, 有长这样的 也有长这样的 尽管这些菜单的相貌都不尽相同, 在功能实现的本质上却都是相同的.实现程序的大致流程如下 读取服务器端的菜单数据 ...

  5. 实现高效的GPRS驱动程序

    1. 引言 用过几款GPRS模块,也从淘宝上买过多个GPRS模块,一般的都会送一个驱动程序和使用demo,但是代码质量都较低. 回头看了下几年前使用的GPRS代码,从今天的角度来看,也就是买模块赠送一 ...

  6. 2017.3.12 H5学习的第一周

    本周我开始了H5的学习,在这一周里我们从html的基本标签开始一直讲到了才算css的用法,接下来我将记录下来本周我学到的H5的内容. 首先是声明文档,声明文档类型是HTML5文件,它在HTML文档必不 ...

  7. Python os与sys模块解析

    os与sys模块的官方解释如下: os: This module provides a portable way of using operating system dependent functio ...

  8. idea + mybatis generator + maven 插件使用

    idea + mybatis generator + maven 插件使用 采用的是 generator 的 maven 插件的方式 ~ 1 pom.xml mybatis其它配置一样,下面是配置my ...

  9. 数据泵 TTS(传输表空间技术)

    1.源库准备环境 --创建被传输的表空间create tablespace tts logging datafile '/home/oracle/app/oradata/orcl/tts01.dbf' ...

  10. ElasticSearch集群安装配置

    1. 环境说明 Cent OS 7 jdk-8u121-linux-x64.tar.gz elasticsearch-5.2.1.zip 2. 系统环境配置 新建进程用户 修改File Descrip ...