题目链接

一共n个盒子, 两种操作, 第一种是给出两个数x, y, 从第x个盒子开始放y朵花, 一个盒子只能放一朵, 如果某个盒子已经有了, 那么就跳过这个盒子放下面的盒子。 直到花放完了或者到了最后一个盒子。 输出放的第一朵花和最后一朵花的坐标, 如果一朵也没法放, 输出Can not put any one.

第二种操作, 给出l, r, 求l, r区间内有多少朵花, 输出, 并且将l, r内的盒子全部变空。

思路: 第二种操作比较简单, 区间查询然后区间置0就可以。

第一种操作, 首先查询[x, n]内一共有多少个盒子是空的, 如果全是满的, 直接输出Can not put any one.  设num为空盒子的数量, 那么显然y = min(y, num)。

接下来的问题就是找左右端点, 我是用的二分寻找左右端点, 具体的细节可以看代码。

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
const int maxn = 5e4+;
int sum[maxn<<], cnt[maxn<<], n;
void pushUp(int rt) {
sum[rt] = sum[rt<<]+sum[rt<<|];
}
void pushDown(int rt, int m) {
if(~cnt[rt]) {
cnt[rt<<] = cnt[rt<<|] = cnt[rt];
sum[rt<<] = cnt[rt]*(m-(m>>));
sum[rt<<|] = cnt[rt]*(m>>);
cnt[rt] = -;
}
}
void update(int L, int R, int l, int r, int rt, int val) {
if(L<=l&&R>=r) {
cnt[rt] = val;
sum[rt] = val*(r-l+);
return ;
}
pushDown(rt, r-l+);
int m = l+r>>;
if(L<=m)
update(L, R, lson, val);
if(R>m)
update(L, R, rson, val);
pushUp(rt);
}
int query(int L, int R, int l, int r, int rt) {
if(L<=l&&R>=r) {
return sum[rt];
}
pushDown(rt, r-l+);
int m = l+r>>, ret = ;
if(L<=m)
ret += query(L, R, lson);
if(R>m)
ret += query(L, R, rson);
return ret;
}
int bin(int l, int r, int val) {
int ans, pos = l;
while(l<=r) {
int m = l+r>>;
if(m-pos+-query(pos, m, , n, )>=val) {
r = m-;
ans = m;
} else {
l = m+;
}
}
return ans;
}
int main()
{
int t, m, x, y, sign;
cin>>t;
while(t--) {
scanf("%d%d", &n, &m);
mem1(cnt);
mem(sum);
while(m--) {
scanf("%d%d%d", &sign, &x, &y);
x++;
if(sign == ) {
int num = query(x, n, , n, );
if(num == n-x+) {
puts("Can not put any one.");
continue;
}
y = min(y, n-x+-num);
int l = bin(x, n, );
int r = bin(l, n, y);
printf("%d %d\n", l-, r-);
update(l, r, , n, , );
} else {
y++;
printf("%d\n", query(x, y, , n, ));
update(x, y, , n, , );
}
}
cout<<endl;
}
return ;
}

hdu 4614 Vases and Flowers 线段树的更多相关文章

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

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

  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 (2013多校2 1004 线段树)

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

  4. HDU 4614 Vases and Flowers(二分+线段树区间查询修改)

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

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

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

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

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

  7. HDU 4614 Vases and Flowers (2013多校第二场线段树)

    题意摘自:http://blog.csdn.net/kdqzzxxcc/article/details/9474169 ORZZ 题意:给你N个花瓶,编号是0 到 N - 1 ,初始状态花瓶是空的,每 ...

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

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

  9. hdu 4614 Vases and Flowers

    http://acm.hdu.edu.cn/showproblem.php?pid=4614 直接线段树维护 代码: #include<iostream> #include<cstd ...

随机推荐

  1. hdu - 1757 - A Simple Math Problem

    题意:当x < 10时, f(x) = x: 当x >= 10 时,f(x) = a0 * f(x-1) + a1 * f(x-2) +  + a2 * f(x-3) + …… + a9 ...

  2. 使用rowid和rownum获取记录时要注意的问题

    我们知道.rowid和rownum在Oracle中都是能够被当做伪劣使用的,主要用来定位表中特定的记录,但它们是有差别的,rowid是和行记录的物理地址相应的.而rownum则不是,是通过返回的记录集 ...

  3. Bootstrap学习之一起步

    说起Bootstrap,第一次接触到这个名词的时候还是同事在做自适应页面技术分享会时了解到,在之后的项目中就逐渐应用了这个前端WEB CSS框架.      

  4. Asp.Net写文本日志

    底层代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespac ...

  5. 在win7下装ubuntu(硬盘版安装)及遇到的问题

    都怪自己弄什么Ubuntu下的Android Studio,因为GFW,gradle总下载不了,用命令行下载一半关机了,然后Ubuntu就这样被我搞残废了.又张罗着重装. 其实就是参照网上的帖子,算是 ...

  6. 在ProgressBar上加文字----显示百分比的进度条

    http://www.cnblogs.com/3dant/archive/2011/04/25/2026776.html

  7. VS2012破解_序列号

    中文版:http://download.microsoft.com/download/B/0/F/B0F589ED-F1B7-478C-849A-02C8395D0995/VS2012_ULT_chs ...

  8. [C++]Infinite House of Pancakes——Google Code Jam 2015 Qualification Round

    Problem It’s opening night at the opera, and your friend is the prima donna (the lead female singer) ...

  9. HTML标签解释大全

      一.HTML标记 标签:!DOCTYPE 说明:指定了 HTML 文档遵循的文档类型定义(DTD).   标签:a 说明:标明超链接的起始或目的位置.   标签:acronym 说明:标明缩写词. ...

  10. TCP的阻塞和重传

    TCP的阻塞和重传 TCP的阻塞和重传机制 网络拥堵 现在网络上大部分的网络请求都是以TCP的方式进行传输的了.网络链路是固定的,各种链路情况也是不一样的.网络拥堵一直是TCP协议设计和使用的时候尽力 ...