题目大意:爱丽丝有N个花瓶,每个花瓶最多放一朵花。然后又如下两个操作。

1:A B    从第A个花瓶开始,往后依次插B朵花,直到不能插为止。如果一朵花都不能插入就输出“can.....”,否则输出第一个插花位置和最后一个插花位置。

2:A B    输出A B 之间有多少朵花   然后将这些花瓶清空。

当时比赛的时候始终找不到办法求出 最后一个插花位置。  也想过二分  但是想着怕效率太慢就没写。

其实最后想想也是 只有50000个操作   再乘以log N的二分  最多也就20W左右吧。

我是弱菜,自己写的程序效率巨慢。而且数组也开得多。

思路:

用lef 记录每个区间最左边可以放的花瓶,如果没有就是INF

用rig 记录每个区间最右边可以放的花瓶,如果没有就是-1

以上两个在更新的时候  lef选较小的   rig选较大的

cov表示区间全空 0 还是全满1  ,或者是不空不满  -1

然后emp表示区间空花瓶数。

主要的难点就是可以插花的时候怎么找到最后一个插花位置。

那么就用二分  找那个 emp ==  所需要插花的数量 的最小右边的区间。

详见代码。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#define maxn 50005
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define INF 0x3f3f3f3f
using namespace std; int emp[maxn<<2];
int cov[maxn<<2];
int lef[maxn<<2];
int lzy[maxn<<2];
int rig[maxn<<2]; void pushup(int num)
{
emp[num]=emp[num<<1]+emp[num<<1|1]; if(cov[num<<1]==0 && cov[num<<1|1]==0)cov[num]==0;
else if(cov[num<<1|1]==1 && cov[num<<1]==1)cov[num]=1;
else cov[num]=-1;
lef[num]=min(lef[num<<1],lef[num<<1|1]);
rig[num]=max(rig[num<<1|1],rig[num<<1]);
} void pushdown(int num,int s,int e)
{
if(lzy[num]!=0)
{
int mid=(s+e)>>1; lzy[num<<1]=lzy[num<<1|1]=lzy[num]; if(cov[num]!=-1)cov[num<<1]=cov[num<<1|1]=cov[num]; if(cov[num<<1]==0)emp[num<<1]=mid-s+1;
else if(cov[num<<1]==1)emp[num<<1]=0; if(cov[num<<1|1]==0)emp[num<<1|1]=e-mid;
else if(cov[num<<1|1]==1)emp[num<<1|1]=0; if(cov[num]==0)
{
lef[num<<1]=s;
rig[num<<1]=mid;
lef[num<<1|1]=mid+1;
rig[num<<1|1]=e;
}
else
{
lef[num<<1]=lef[num<<1|1]=INF;
rig[num<<1]=rig[num<<1|1]=-1;
}
lzy[num]=0;
}
} void build(int num,int s,int e)
{
cov[num]=0;
lef[num]=s;
rig[num]=e;
emp[num]=e-s+1;
lzy[num]=0;
if(s==e)return;
int mid=(s+e)>>1; build(lson);
build(rson);
pushup(num);
} void update(int num,int s,int e,int l,int r,int val)
{
if(l<=s && r>=e)
{
lzy[num]=1;
cov[num]=val;
emp[num]=val==0?e-s+1:0;
lef[num]=val==0?s:INF;
rig[num]=val==0?e:-1;
return;
}
pushdown(num,s,e);
int mid=(s+e)>>1;
if(l<=mid)update(lson,l,r,val);
if(r>mid)update(rson,l,r,val);
pushup(num);
} int query(int num,int s,int e,int l,int r)
{
//printf("emp=%d,s=%d,e=%d,l=%d,r=%d,cov=%d\n",emp[num],s,e,l,r,cov[num]);
if(l<=s && r>=e)
{
return emp[num];
}
pushdown(num,s,e);
int mid=(s+e)>>1;
if(r<=mid)return query(lson,l,r);
else if(l>mid)return query(rson,l,r);
else return query(lson,l,mid)+query(rson,mid+1,r);
pushup(num);
} int Q_L(int num,int s,int e,int l,int r)//找到区间的LEF
{
if(l==s && r==e)
{
return lef[num];
} pushdown(num,s,e);
int mid=(s+e)>>1;
if(r<=mid)return Q_L(lson,l,r);
else if(l>mid)return Q_L(rson,l,r);
else return min(Q_L(lson,l,mid),Q_L(rson,mid+1,r));
pushup(num);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m); build(1,1,n);//额额额。 我是用1-N 建的树 而题目说的是 0-N-1 所以。。。后面有一些++操作。。。
int tl,tr;
while(m--)
{
int op,aa,bb;
scanf("%d%d%d",&op,&aa,&bb); if(op==1)
{
aa++;
int ll=Q_L(1,1,n,aa,n);//找到左边
if(ll==INF)
{
printf("Can not put any one.\n");
continue;
}
printf("%d ",ll-1);
int ttmp=query(1,1,n,ll,n); if(ttmp==0)
printf("Can not put any one.\n");
else
{
if(ttmp<=bb)
{
printf("%d\n",rig[1]-1);
update(1,1,n,ll,n,1);
}
else
{
int top=n,bot=ll,mid;
while(bot<=top)
{
mid=(bot+top)>>1;
int bin=query(1,1,n,ll,mid);
if(bin>bb)
top=mid-1;
else if(bin<bb)
bot=mid+1;
else break;
}
while(query(1,1,n,ll,mid)==bb)//找到最小的
{
mid--;
if(mid<=ll)break;
}
printf("%d\n",mid+1-1);
update(1,1,n,ll,mid+1,1);
}
}
}
else
{
aa++,bb++;
printf("%d\n",bb-aa+1-query(1,1,n,aa,bb));
update(1,1,n,aa,bb,0);
}
}
puts("");
}
return 0;
}

hdu 4614 Vases and Flowers (二分 线段树)的更多相关文章

  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 ...

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

    Vases and Flowers Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others ...

  3. HDU 4614 Vases and Flowers 【线段树】+【二分】

    <题目链接> 题目大意: 有n个花瓶,每个花瓶中只能放一朵花.两种操作,一种是从A开始放F朵花,如果有的花瓶中已经有花则跳过这个花瓶,往下一个花瓶放:第二种是将区间[A,B]之间花瓶中的花 ...

  4. HDU 4614 Vases and Flowers(线段树+记录区间始末点或乱搞)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614 题目大意:有n个空花瓶,有两种操作: 操作①:给出两个数字A,B,表示从第A个花瓶开始插花,插B ...

  5. hdu 4614 Vases and Flowers(线段树:成段更新)

    线段树裸题.自己写复杂了,准确说是没想清楚就敲了. 先是建点为已插花之和,其实和未插花是一个道理,可是开始是小绕,后来滚雪球了,跪了. 重新建图,分解询问1为:找出真正插画的开始点和终止点,做成段更新 ...

  6. hdu 4614 Vases and Flowers(线段树)

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

  7. HDU4614 Vases and Flowers 二分+线段树

    分析:感觉一看就是二分+线段树,没啥好想的,唯一注意,当开始摆花时,注意和最多能放的比大小 #include<iostream> #include<cmath> #includ ...

  8. HDU - 4614 Vases and Flowers(二分+区间修改)

    https://cn.vjudge.net/problem/HDU-4614 题意 n个花瓶,m个操作,花瓶里面有的有花,有的是空的.1操作是从a开始往右放b朵花,花瓶有了的不放,跳过,直到a右边都放 ...

  9. 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 ...

  10. 【HDU 4614】Vases and Flowers(线段树区间更新懒惰标记)

    题目0到n-1的花瓶,操作1在下标a开始插b朵花,输出始末下标.操作2清空[a,b]的花瓶,求清除的花的数量.线段树懒惰标记来更新区间.操作1,先查询0到a-1有num个空瓶子,然后用线段树的性质,或 ...

随机推荐

  1. C++之对象组合

    #include<stdio.h>//初始化列表 提供了对成员变量初始化的方式//Constructor        class M      {       private:      ...

  2. Jquery调用webService的四种方法 转载-记录

    我总结几个关键点 1. 服务必须声明为ScriptService(否则会出现下面的问题) 2.服务的方法不需要任何更改,保持原状 3.客户端用jquery的.ajax方法来调用 3.1 type必须是 ...

  3. 1724: [Usaco2006 Nov]Fence Repair 切割木板( 贪心 )

    倒过来看 , 每次总是选择最短的两块木板合并 , 用heap维护 ------------------------------------------------------------------- ...

  4. Yii2归档安装法

    打开dos 操作命令  1.先把init.bat  拖到dos命令窗口 打开 (如果拖过去没打开 可以回车Enter一下) 这里需要注意一下  下图红圈中是两种环境  0->开发环境  1-&g ...

  5. django virtualenv

    1. virtualenv virtualenv用于创建独立的Python环境,多个Python相互独立,互不影响,它能够:1. 在没有权限的情况下安装新套件2. 不同应用可以使用不同的套件版本3. ...

  6. 建房子之前先挖地基 - Java BlockingQueue理解

    最近一直在看<Think In Java>里关于并发部分的章节,读到第二十一章有一个有趣的比喻:必须先挖房子的地基,但是接下来可以并行的铺设钢结构和构建水泥部件,而这两项任务必须在混凝土浇 ...

  7. [置顶] JAVA概述(6)常量,关键字,进制转换

    21.关键字.... 变量: 就是将不确定的数据进行存储.也就是需要在内粗恩中开辟一个空间. 整数类型   1个字节 byte                    占 8位 -128~~~127 2 ...

  8. frame和bounds的区别

    frame:根据父视图坐标系来确定自己的位置 bounds:该视图在自己坐标系的位置和大小 修改bounds并不会引起视图位置的变化,会影响自身子视图的位置:修改frame会引起视图位置的变化 UIV ...

  9. 一旦配置oracle em经验

    对oracle10grac构造em,原本很easy事儿,但它需要一个很长的时间,记录下来.MEMO. 首先,例如,报告了以下错误: [oracle@node1 admin]$ emca -config ...

  10. HDU OJ 5326 Work( 2015多校联合训练第3场) 并查集

    题目连接:戳ME #include <iostream> #include <cstdio> #include <cstring> using namespace ...