HDU 4614 Vases and Flowers(线段树+记录区间始末点或乱搞)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614
题目大意:有n个空花瓶,有两种操作:
操作①:给出两个数字A,B,表示从第A个花瓶开始插花,插B朵花,输出第一个和最后一个插入的花瓶,如果任意花瓶都已经满了不能插花,则输出“Can not put any one.”。
操作②:给出两个数字A,B,表示清空第A~B个花瓶,并输出清空掉的花朵数目。
解题思路:线段树,关于操作②,很简单弄个sum表示区间空花瓶数,计算时清空掉的花朵数=区间长度-sum。
关于操作①,有两种解法,第一种就是记录更新每个区间的空花瓶的始末点,这样在插花时可以由此直接获得起点终点。
第二种,就是乱搞,查找全空区间(都是空花瓶)然后插花,全空区间起点终点的获得就不用说了吧。复杂度真的是玄学(感觉完全算不出来),还以为会超时的,竟然比解法一还快点。。。
解法一:
#include<stdio.h>
#include<algorithm>
#define LC(a) ((a<<1))
#define RC(a) ((a<<1)+1)
#define MID(a,b) ((a+b)>>1)
using namespace std;
typedef long long ll;
const int N = 5e4 + ; struct node {
ll l, r;
ll sum, Start, End, color;//Start是第一个空花瓶位置,End是最后一个空花瓶位置,color=-1,0,1代表初始化,清空,插花
}tree[N<<]; ll leave, Start, sum, End;
void pushup(ll p) {
//维护区间空花瓶数量
tree[p].sum = tree[LC(p)].sum + tree[RC(p)].sum;
tree[p].color = (tree[LC(p)].color == tree[RC(p)].color ? tree[LC(p)].color : -);
//维护空花瓶起点和终点
if (tree[LC(p)].Start != )
tree[p].Start = tree[LC(p)].Start;
else if (tree[LC(p)].End != )
tree[p].Start = tree[LC(p)].End;
else if (tree[RC(p)].Start != )
tree[p].Start = tree[RC(p)].Start;
else if (tree[RC(p)].End != )
tree[p].Start = tree[RC(p)].End;
else
tree[p].Start = ;
tree[p].End = max(max(tree[LC(p)].Start, tree[LC(p)].End), max(tree[RC(p)].Start, tree[RC(p)].End));
} void pushdown(ll p) {
if (tree[p].color == ) {
tree[LC(p)].sum = tree[LC(p)].r - tree[LC(p)].l + ;
tree[LC(p)].Start = tree[LC(p)].l;
tree[LC(p)].End = tree[LC(p)].r;
tree[RC(p)].sum = tree[RC(p)].r - tree[RC(p)].l + ;
tree[RC(p)].Start = tree[RC(p)].l;
tree[RC(p)].End = tree[RC(p)].r;
tree[LC(p)].color = tree[RC(p)].color = ;
}
else if (tree[p].color == ) {
tree[LC(p)].sum = tree[LC(p)].Start = tree[LC(p)].End = tree[RC(p)].sum = tree[RC(p)].Start = tree[RC(p)].End = ;
tree[LC(p)].color = tree[RC(p)].color = ;
}
} void build(ll p, ll l, ll r) {
tree[p].l = l;
tree[p].r = r;
tree[p].Start = tree[p].End = ;
tree[p].sum = ;
if (l == r) {
tree[p].Start = tree[p].End = l;
tree[p].sum = ;
tree[p].color = -;
return;
}
build(LC(p), l, MID(l, r));
build(RC(p), MID(l, r) + , r);
pushup(p);
}
//清空
void update(ll p, ll l, ll r) {
if (r<tree[p].l || l>tree[p].r)
return;
if (l <= tree[p].l&&r >= tree[p].r) {
sum += (tree[p].r - tree[p].l + - tree[p].sum);
tree[p].Start = tree[p].l;
tree[p].End = tree[p].r;
tree[p].sum = tree[p].r - tree[p].l + ;
tree[p].color = ;
return;
}
pushdown(p);
update(LC(p), l, r);
update(RC(p), l, r);
pushup(p);
}
//插花
void query(ll p, ll l, ll r) {
if (r<tree[p].l || l>tree[p].r)
return;
if (leave == || tree[p].sum == )
return;
if (l <= tree[p].l&&r >= tree[p].r) {
if (Start == )
Start = tree[p].Start;
if (leave >= tree[p].sum) {
leave -= tree[p].sum;
End = max(End, tree[p].End);
tree[p].sum = tree[p].Start = tree[p].End = ;
tree[p].color = ;
return;
}
}
pushdown(p);
query(LC(p), l, r);
query(RC(p), l, r);
pushup(p);
}
int main() {
ll q;
scanf("%I64d",&q);
while (q--) {
ll n, m;
scanf("%I64d %I64d",&n,&m);
build(, , n);
while (m--) {
ll k;
scanf("%I64d",&k);
//插花
if (k == ) {
ll a, f;
scanf("%I64d %I64d",&a,&f);
End = Start = ;
leave = f;
query(, a + , n);
if (Start == )
printf("Can not put any one.\n");
else
printf("%I64d %I64d\n",Start-,End-);
}
//清空
else {
ll a, b;
scanf("%I64d %I64d",&a,&b);
sum = ;
update(, a + , b + );
printf("%I64d\n",sum);
}
}
printf("\n");
}
return ;
}
解法二:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<string>
#define LC(a) (a<<1)
#define RC(a) (a<<1|1)
#define MID(a,b) ((a+b)>>1)
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const int N=5e4+; int ans,x,Start,End,flag; struct node{
int sum,l,r;//sum表示空花瓶数
}tree[*N]; void pushdown(int p){
//全满
if(tree[p].sum==tree[p].r-tree[p].l+){
tree[LC(p)].sum=tree[LC(p)].r-tree[LC(p)].l+;
tree[RC(p)].sum=tree[RC(p)].r-tree[RC(p)].l+;
}
//全空
else if(tree[p].sum==)
tree[LC(p)].sum=tree[RC(p)].sum=;
} void pushup(int p){
tree[p].sum=tree[LC(p)].sum+tree[RC(p)].sum;
} void build(int p,int l,int r){
tree[p].l=l;
tree[p].r=r;
if(l==r){
tree[p].sum=;
return;
}
build(LC(p),l,MID(l,r));
build(RC(p),MID(l,r)+,r);
pushup(p);
} void update(int p,int l,int r){
if(l>tree[p].r||r<tree[p].l)
return;
if(x<=)
return;
if(l<=tree[p].l&&r>=tree[p].r){
if(tree[p].sum==)
return;
//找到全空区间
if(x>=tree[p].sum&&tree[p].sum==tree[p].r-tree[p].l+){
if(flag==){
Start=tree[p].l;
flag++;
}
x-=tree[p].sum;
tree[p].sum=;
End=tree[p].r;
return;
}
}
pushdown(p);
update(LC(p),l,r);
update(RC(p),l,r);
pushup(p);
} void query(int p,int l,int r){
if(l>tree[p].r||r<tree[p].l)
return;
if(l<=tree[p].l&&r>=tree[p].r){
ans+=tree[p].r-tree[p].l+-tree[p].sum;
tree[p].sum=tree[p].r-tree[p].l+;
return;
}
pushdown(p);
query(LC(p),l,r);
query(RC(p),l,r);
pushup(p);
} int main(){
int T;
scanf("%d",&T);
while(T--){
int n,q;
scanf("%d%d",&n,&q);
build(,,n-);
while(q--){
int op;
scanf("%d",&op);
if(op==){
int l;
scanf("%d%d",&l,&x);
flag=;
update(,l,n-);
if(flag==)
printf("Can not put any one.\n");
else
printf("%d %d\n",Start,End);
}
else{
int l,r;
scanf("%d%d",&l,&r);
ans=;
query(,l,r);
printf("%d\n",ans);
}
}
printf("\n");
}
return ;
}
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 (2013多校第二场线段树)
题意摘自:http://blog.csdn.net/kdqzzxxcc/article/details/9474169 ORZZ 题意:给你N个花瓶,编号是0 到 N - 1 ,初始状态花瓶是空的,每 ...
- HDU-4614 Vases and Flowers 线段树区间更新
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614 线段树保存区间是否被覆盖以及区间的和即可,在询问的时候在线段树上二分查找就可以了...代码写得比 ...
- hdu4614 Vases and Flowers 线段树+二分
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614 题意: 给你N个花瓶,编号是0 到 N - 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 ...
- hdu 1754 I Hate It (线段树求区间最值)
HDU1754 I Hate It Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u D ...
- 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 ...
随机推荐
- 前端基础----jquery
一.jQuery是什么? <1> jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. <2>jQuery是继 ...
- java发送邮件功能[转]
原文链接:https://blog.csdn.net/jjkang_/article/details/56521959 Javamail遵循两个协议,一个是smtp协议,另一个是pop3协议.一般情况 ...
- move_base代码学习一
System overview move_base 源码 API nav_core BaseGlobalPlanner BaseLocalPlanner RecoveryBehavior Recove ...
- STL源码分析-hashtable
http://note.youdao.com/noteshare?id=5c8d2b09c0f72af9a12b0ed2023a338d
- Patch multi versions of windows via Power shell
Patch multi versions of windows via Power shell $version = Get-WmiObject -Class Win32_OperatingSyste ...
- Tensorflow BatchNormalization详解:3_使用tf.layers高级函数来构建带有BatchNormalization的神经网络
Batch Normalization: 使用tf.layers高级函数来构建带有Batch Normalization的神经网络 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 吴 ...
- linux之nginx的安装
(一)这次是自己折腾服务器的环境,所以自己算是都装过一遍,在装的过程中也是在网上搜索,其实最后在公司运维的指导下知道自己安装出错在哪里的.不说了,直接说安装和问题 (二):首先从 http://ngi ...
- webpack4.0.1安装问题及解决方法
2月底的时候,webpack4正式发布了,但是当我们安装之后,使用下面的语句来打包的时候,发现打包失败了 webpack ./src/main.js ./dist/bundle.js 并且给出了下面这 ...
- Python学习笔记(十八)@property
# 请利用@property给一个Screen对象加上width和height属性, # 以及一个只读属性resolution: # -*- coding: utf-8 -*- class Scree ...
- 【Nginx】修改响应头,根据不同请求IP重定向到不同IP
背景: 使用CAS登录的过程中会涉及到三次重定向,如果在同一个局域网内,是没有任何问题的,但如果涉及到跨网访问,这个问题就比较蛋疼了. 解决思路: 通过Nginx对要访问的系统进行代理,根据请求IP来 ...