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

题意:

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

然后有2个操作。

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

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

操作看起来挺简单的但写起来还是有点复杂的

首先建树的时候可以设置变量first与ends分别表示一个区间最先出现的0和最后出现的0,sum=0

表示没放东西,sum=1表示放了。我们可以用二分来查找插完b朵花后的结尾区间。然后在寻找这个

区间的first与ends值之后就简单了。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int M = 5e4 + 10;
struct TnT {
int l , r , num , add , first , ends;
}T[M << 2];
int n , m;
void build(int l , int r , int p) {
int mid = (l + r) >> 1;
T[p].l = l , T[p].r = r , T[p].add = T[p].num = 0 , T[p].first = l , T[p].ends = r;
if(l == r) {
return ;
}
build(l , mid , p << 1);
build(mid + 1 , r , (p << 1) | 1);
}
void pushup(int p) {
T[p].num = T[p << 1].num + T[(p << 1) | 1].num;
if(T[p << 1].first == -1) {
T[p].first = T[(p << 1) | 1].first;
}
else if(T[(p << 1) | 1].first == -1) {
T[p].first = T[p << 1].first;
}
else {
T[p].first = min(T[(p << 1) | 1].first , T[p << 1].first);
}
if(T[(p << 1) | 1].ends == -1) {
T[p].ends = T[(p << 1) | 1].ends;
}
else if(T[(p << 1) | 1].ends == -1) {
T[p].ends = T[p << 1].ends;
}
else {
T[p].ends = max(T[(p << 1) | 1].ends , T[p << 1].ends);
}
}
void pushdown(int p) {
if(T[p].add == 1) {
T[p << 1].num = T[p << 1].r - T[p << 1].l + 1;
T[p << 1].first = -1;
T[p << 1].ends = -1;
T[(p << 1) | 1].num = T[(p << 1) | 1].r - T[(p << 1) | 1].l + 1;
T[(p << 1) | 1].first = -1;
T[(p << 1) | 1].ends = -1;
T[p << 1].add = T[p].add;
T[(p << 1) | 1].add = T[p].add;
}
if(T[p].add == -1) {
T[p << 1].first = T[p << 1].l;
T[p << 1].ends = T[p << 1].r;
T[p << 1].num = 0;
T[(p << 1) | 1].num = 0;
T[p << 1].add = T[p].add;
T[(p << 1) | 1].first = T[(p << 1) | 1].l;
T[(p << 1) | 1].ends = T[(p << 1) | 1].r;
T[(p << 1) | 1].add = T[p].add;
}
T[p].add = 0;
}
int query(int l , int r , int p) {
int mid = (T[p].l + T[p].r) >> 1;
if(T[p].l == l && T[p].r == r) {
return T[p].num;
}
pushdown(p);
if(mid >= r) {
return query(l , r , p << 1);
}
else if(mid < l) {
return query(l , r , (p << 1) | 1);
}
else {
return query(l , mid , p << 1) + query(mid + 1 , r , (p << 1) | 1);
}
}
int queryfr(int l , int r , int p) {
int mid = (T[p].l + T[p].r) >> 1;
if(T[p].l == l && T[p].r == r) {
return T[p].first;
}
pushdown(p);
if(mid >= r) {
return queryfr(l , r , p << 1);
}
else if(mid < l) {
return queryfr(l , r , (p << 1) | 1);
}
else {
int ans = queryfr(l , mid , p << 1);
if(ans == -1) {
return queryfr(mid + 1 , r , (p << 1) | 1);
}
else {
return ans;
}
}
}
int queryed(int l , int r , int p) {
int mid = (T[p].l + T[p].l) >> 1;
if(T[p].l == l && T[p].r == r) {
return T[p].ends;
}
pushdown(p);
if(mid >= r) {
return queryed(l , r , p << 1);
}
else if(mid < l) {
return queryed(l , r , (p << 1) | 1);
}
else {
int ans = queryed(mid + 1 , r , (p << 1) | 1);
if(ans == -1) {
return queryed(l , mid , p << 1);
}
else {
return ans;
}
}
}
void updata(int l , int r , int p , int ad) {
int mid = (T[p].l + T[p].r) >> 1;
if(T[p].l == l && T[p].r == r) {
if(ad == 1) {
T[p].add = 1;
T[p].num = T[p].r - T[p].l + 1;
T[p].first = -1;
T[p].ends = -1;
return ;
}
if(ad == -1) {
T[p].add = -1;
T[p].num = 0;
T[p].first = T[p].l;
T[p].ends = T[p].r;
return ;
}
}
pushdown(p);
if(mid >= r) {
updata(l , r , p << 1 , ad);
}
else if(mid < l) {
updata(l , r , (p << 1) | 1 , ad);
}
else {
updata(l , mid , p << 1 , ad);
updata(mid + 1 , r , (p << 1) | 1 , ad);
}
pushup(p);
}
int bisearch(int sta , int sum) {
int l = sta , r = n;
int ans = n;
while(l <= r) {
int mid = (l + r) >> 1;
int gg = query(sta , mid , 1);
gg = mid - sta + 1 - gg;
if(gg >= sum) {
r = mid - 1;
ans = mid;
}
else {
l = mid + 1;
}
}
return ans;
}
int main() {
int t;
scanf("%d" , &t);
while(t--) {
scanf("%d%d" , &n , &m);
build(1 , n , 1);
for(int i = 1 ; i <= m ; i++) {
int k , a , f;
scanf("%d%d%d" , &k , &a , &f);
if(k == 1) {
a++;
int res = query(a , n , 1);
res = n - a + 1 - res;
if(res == 0) {
printf("Can not put any one.\n");
continue;
}
int sum = min(res , f);
int ed = bisearch(a , sum);
int fr = queryfr(a , ed , 1);
updata(fr , ed , 1 , 1);
printf("%d %d\n" , fr - 1 , ed - 1);
}
if(k == 2) {
a++ , f++;
int res = query(a , f , 1);
updata(a , f , 1 , -1);
printf("%d\n" , res);
}
}
printf("\n");
}
return 0;
}

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

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

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

  2. hdu 4614 Vases and Flowers 线段树

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  10. hdu 4614 Vases and Flowers

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

随机推荐

  1. codeforces 340 A. The Wall

    水水的一道题,只需要找xy的最小公倍数,然后找a b区间有多少个可以被xy的最小公倍数整除的数,就是答案. //============================================ ...

  2. word 文档导出 (freemaker+jacob)--java开发

    工作中终于遇到了 需要导出word文旦的需求了.由于以前没有操作过,所以就先百度下了,基本上是:博客园,简书,CDSN,这几大机构的相关帖子比较多,然后花了2周时间 才初步弄懂.  学习顺序: 第一阶 ...

  3. pod指定node运行

    1.给node打上label kubectl label nodes cn-hongkong.i-j6c5pm0b59y9kaos565o apptype=monitoring 2.查看结果kubec ...

  4. MyBatis 核心配置综述之 ParameterHandler

    目录 ParameterHandler 简介 ParameterHandler 创建 ParameterHandler 中的参数从何而来 ParameterHandler 解析 MyBatis 四大核 ...

  5. Linux下,为应用程序添加桌面图标(ubuntu18.4)

    一.桌面图标位置 Lniux下桌面图标储存路径为:/usr/share/applications 二.桌面图标格式 所有桌面图标格式均为desktop,即名为XXX.desktop 三.编辑内容(常用 ...

  6. jQuery发送Ajax请求以及出现的问题

    普通jQuery的Ajax请求代码如下: $.ajax({ type: 'POST', url: "http://xxx/yyy/zzz/sendVerifyCode", data ...

  7. powerdesign进军(一)--安装破解

    目录 资源下载地址 安装powerdesign 破解powerdesign 汉化 总结 IT行业不管是web开发还是客户端开发都需要数据库,因为现在是数据时代能够拥有强大的数据就是行业的王者.目前一些 ...

  8. CodeForces 1129C Morse Code

    洛谷题目页面传送门 & CodeForces题目页面传送门 题意见洛谷里的翻译. 首先我们可以用区间DP算出对于每个子01串,能表示的字母串的个数. 设\(dp_{i,j}\)表示长度为\(i ...

  9. 洛谷 P4124 [CQOI2016]手机号码

    题意简述 求l~r之间不含前导零,至少有三个相邻的相同数字,不同时含有4和8的11位正整数的个数 题解思路 数位DP,注意在l,r位数不够时补至11位 代码 #include <cstdio&g ...

  10. 对微软的敌视何时休? 从一篇语言评论文章对C#的评价说起

    看到一篇公众号文章<2020年什么编程语言最受欢迎,待遇最高?>,其中对C#的描述如下: 点击阅读原文,看到这是一篇翻译文章:https://codinginfinite.com/top- ...