hdu 4614 Vases and Flowers(线段树)
题目链接: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(线段树)的更多相关文章
- HDU 4614 Vases and Flowers(线段树+二分)
题目链接 比赛的时候一直想用树状数组,但是树状数组区间更新之后,功能有局限性.线段树中的lz标记很强大,这个题的题意也挺纠结的. k = 1时,从a开始,插b个花,输出第一个插的位置,最后一个的位置, ...
- hdu 4614 Vases and Flowers 线段树
题目链接 一共n个盒子, 两种操作, 第一种是给出两个数x, y, 从第x个盒子开始放y朵花, 一个盒子只能放一朵, 如果某个盒子已经有了, 那么就跳过这个盒子放下面的盒子. 直到花放完了或者到了最后 ...
- HDU 4614 Vases and Flowers(线段树+二分)
Vases and Flowers Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others ...
- 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 ...
- HDU 4614 Vases and Flowers(二分+线段树区间查询修改)
描述Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to ...
- HDU 4614 Vases and Flowers(线段树+记录区间始末点或乱搞)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614 题目大意:有n个空花瓶,有两种操作: 操作①:给出两个数字A,B,表示从第A个花瓶开始插花,插B ...
- hdu 4614 Vases and Flowers(线段树:成段更新)
线段树裸题.自己写复杂了,准确说是没想清楚就敲了. 先是建点为已插花之和,其实和未插花是一个道理,可是开始是小绕,后来滚雪球了,跪了. 重新建图,分解询问1为:找出真正插画的开始点和终止点,做成段更新 ...
- HDU 4614 Vases and Flowers (2013多校第二场线段树)
题意摘自:http://blog.csdn.net/kdqzzxxcc/article/details/9474169 ORZZ 题意:给你N个花瓶,编号是0 到 N - 1 ,初始状态花瓶是空的,每 ...
- HDU 4614 Vases and Flowers 【线段树】+【二分】
<题目链接> 题目大意: 有n个花瓶,每个花瓶中只能放一朵花.两种操作,一种是从A开始放F朵花,如果有的花瓶中已经有花则跳过这个花瓶,往下一个花瓶放:第二种是将区间[A,B]之间花瓶中的花 ...
- hdu 4614 Vases and Flowers
http://acm.hdu.edu.cn/showproblem.php?pid=4614 直接线段树维护 代码: #include<iostream> #include<cstd ...
随机推荐
- [nghttp2]压测工具,源码编译并进行deb打包过程
编译环境:deepin 15.11桌面版 nghttp2下载地址:https://github.com/nghttp2/nghttp2 环境要求 emm只能在类Linux环境才能完整编译,想在Wind ...
- LeetCode :2.两数相加 解题报告及算法优化思路
题目连接:2.两数相加 题意 题目难度标为 中等, 因为题意上有一部分理解难度,以及需要数据结构的链表基础. 还不知道到链表的童鞋可以粗略的看下百度百科或者是翻出数据结构的书看一看,通俗一点的语言来解 ...
- [NUnit] discover test finished: 0 found issue
%Temp%\VisualStudioTestExplorerExtensions & restart visual studio
- Python 环境管理
Python 版本管理器:pyenv zsh 配置 # 安装 curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv ...
- Codeforces 436D Pudding Monsters
题意简述 开始有无限长的一段格子,有n个格子种有布丁怪兽,一开始连续的布丁怪兽算一个布丁怪兽. 每回合你可以将一个布丁怪兽向左或右移动,他会在碰到第一个布丁怪兽时停下,并与其合并. 有m个特殊格子,询 ...
- 8.9 day30 并发编程 进程理论 进程方法 守护进程 互斥锁
多道技术 1.空间上的复用 多个程序共用一套计算机硬件 多道技术原理 2.时间上的复用 切换+保存状态 1.当一个程序遇到IO操作 操作系统会剥夺该程序的CPU执行权限( 提高了CPU的利用率 ...
- linux环境下测试环境搭建
一.linux环境下测试环境搭建过程简述: 1.前端后台代码未分离情况下: 主要步骤为:安装jdk,安装mysql,安装tomcat,将项目代码部署到tomcat/webapps/下. 2.前端后台代 ...
- Cacti 管理员密码忘记找回
1.登陆数据库: # mysql -uroot -p MariaDB [(none)]> show databases; +--------------------+ | Database | ...
- 快应用 吸顶 bug
官网说, 加载页面时,所有元素的appear事件都会被触发一次.因此,需要过滤第一次的appear事件: 但是,即使设置了过滤,也无效 于是,我把show属性改成了if属性,问题就解决 如下图:
- spring、spring mvc与spring boot的区别是什么?
Spring 的功能 Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 ao ...