HDU-4614:Vases and Flowers(线段树+二分)
来源:互联网 发布:棋牌软件开发定制 编辑:程序博客网 时间:2024/06/05 06:26
题目链接:点击打开链接
题目大意:
有n盆花,两种操作。
第一种操作是选择从第几个花盆开始往后,往里面插一些花,如果当前花盆有花就往后面一个花盆插,可以不把花插完,让你输出开始插花的起始坐标和终止坐标。
第二种操作是清除选定区间的花,并输出多少花被清除了。
解题思路:
就是打个区间更新的线段树,每个节点维护一下当前区间内有多少花。然后可以再给个标记,标记一下是否区间满或者空,当然这个可以用区间长度间接表示出来,不过反正要延迟更新,这个标记一下也没啥事儿。
最恶心的就是起始坐标和终止坐标了。我tm把线段树打完死活没想出来怎么搞这个坐标。后来稍微看了一下别人的博客。二分??? WTF ,然后写了一下午二分各种 bug 怀疑人生。唉,最后实在搞不出来就是照着大佬的二分抄了一下,A了。研究了一下之后发现我二分思路是错的,大佬的思路好强啊。。。
我的想法是二分按顺序依次找出每一个空着的点,找到题目要求的那个数量,就好了,然后一下午没写出来,不知道这种思路对不对,自我感觉可能会超时。
正确思路就是直接找最后一个点,起点不动,用二分枚举终点,不断改变终点坐标直至符合要求就解决了。
详细部分看代码,但是因为我查询函数不喜欢写返回值,就很丑。。。
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <vector>#include <queue>#include <map>#include <algorithm>#include <set>#include <functional>#define rank ra#define lson rt<<1#define rson rt<<1|1#define pb push_backusing namespace std;typedef long long ll;const int INF = 1e9 + 5;int n,m,ans,ans1,ans2;struct node{ int l,r,mid; int sum; //区间内花的数量 int flag; //标记}t[250000];void pushup(int rt){ t[rt].sum=t[lson].sum+t[rson].sum;}void pushdown(int rt) //自上往下更新{ if(t[rt].flag) { if(t[rt].flag==2) { t[lson].flag=2; t[lson].sum=t[lson].r-t[lson].l+1; t[rson].flag=2; t[rson].sum=t[rson].r-t[rson].l+1; t[rt].flag=0; } if(t[rt].flag==1) { t[lson].flag=1; t[lson].sum=0; t[rson].flag=1; t[rson].sum=0; t[rt].flag=0; } }}void build(int l,int r,int rt){ int mid=(l+r)>>1; t[rt].l=l;t[rt].r=r; t[rt].mid=mid; t[rt].flag=0; t[rt].sum=0; if(l==r) return ; build(l,mid,lson); build(mid+1,r,rson); pushup(rt);}void update(int l,int r,int flag,int rt) //日常区间更新{ if(l<=t[rt].l&&t[rt].r<=r) { if(flag==1) { t[rt].flag=1; t[rt].sum=0; } if(flag==2) { t[rt].flag=2; t[rt].sum=t[rt].r-t[rt].l+1; } return ; } pushdown(rt); if(l<=t[rt].mid) update(l,r,flag,lson); if(r>t[rt].mid) update(l,r,flag,rson); pushup(rt);}void query(int l,int r,int rt) //没有返回值的查询函数 丑爆{ if(l<=t[rt].l&&t[rt].r<=r) { ans += t[rt].sum; return ; } pushdown(rt); if(l<=t[rt].mid) query(l,r,lson); if(r>t[rt].mid) query(l,r,rson); pushup(rt);}int bin(int s,int rank) //二分找坐标{ int l=s,r=n-1; int res=-1; int mid; while(l<=r) { mid=(l+r)>>1; ans=0; query(s,mid,1); //起点不动 依次枚举终点 if(ans+rank==mid-s+1) { res=mid; r=mid-1; } else { if(ans+rank<mid-s+1) r=mid-1; else l=mid+1; } } return res;}int main(){ int QAQ; scanf("%d",&QAQ); while(QAQ--) { scanf("%d%d",&n,&m); build(0,n-1,1); int c,p,q; for(int i=0;i<m;i++) { scanf("%d%d%d",&c,&p,&q); if(c==1) { ans=0; query(p,n-1,1); if(ans==n-p) printf("Can not put any one.\n"); else { q=min(n-p-ans,q); ans1=bin(p,1); //枚举插花的起点和终点 ans2=bin(p,q); update(ans1,ans2,2,1); printf("%d %d\n",ans1,ans2); } } if(c==2) { ans=0; query(p,q,1); update(p,q,1,1); printf("%d\n",ans); } } printf("\n"); }}
阅读全文
0 0
- hdu 4614 Vases and Flowers(线段树+二分)
- hdu 4614 Vases and Flowers (线段树+二分)
- hdu 4614 Vases and Flowers (二分 线段树)
- hdu 4614 Vases and Flowers 线段树+二分
- HDU 4614 Vases and Flowers(线段树+二分)
- HDU 4614 Vases and Flowers [二分 + 线段树]
- HDU - 4614 Vases and Flowers(线段树 区间修改 二分)
- HDU 4614 Vases and Flowers(线段树、二分)
- HDU 4614 Vases and Flowers (线段树 + 二分)
- hdu 4614线段树+二分Vases and Flowers
- 【解题报告】HDU-4614 Vases and Flowers 线段树+二分
- hdu 4614 Vases and Flowers(线段树+二分)
- HDU-4614:Vases and Flowers(线段树+二分)
- HDU-4614 Vases and Flowers(线段树+区间修改+二分)
- Hdu 4614 Vases and Flowers【二分+线段树】
- HDU 4614 Vases and Flowers——线段树+二分
- HDU-4614 Vases and Flowers (线段树+二分)
- hdu 4614 Vases and Flowers 线段树
- Hive生成MapReduce任务源码分析
- vue 使用总结
- 生信脚本练习(7)求fastq文件质量值分布
- MATLAB 绘制3D Surf
- 剑指offer--对称的二叉树
- HDU-4614:Vases and Flowers(线段树+二分)
- [LeetCode] 38. Count and Say
- python requests解析
- 【Shiro】--- 简介
- POJ 2955 Brackets 区间DP
- ZOJ 1516 Uncle Tom's Inherited Land (二分图匹配)
- 【转载】机器学习计算距离和相似度的方法
- 剑指offer--按之字形顺序打印二叉树
- 引用数据类型---数组