hdu4614 二分+线段树
来源:互联网 发布:算法问题实战策略好吗 编辑:程序博客网 时间:2024/05/14 10:55
题意:给你1-n的花瓶 ,刚开始全是空的,现在有两种操作,
1:从花瓶a开始插入b朵花 如果不能插进去 输出字符串 否则输出最多插入的起点和终点;
2:把a-b的花瓶清空 输出处理花的个数;
结构体数组num【i】表示节点i空瓶的数目
线段树 开始deal函数对整个树初始化,update()更新函数 find()查询区间有多少个空瓶; 对于操作1 关键点是找到起点和终点 这里用二分 在【a,n】进行二分,
先二分起点 注意左右区间的变换(wa了好多次==) 然后在起点和n之间二分终点 最后更新 输出 对于操作2 直接查询即可;
#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define LL(x) (x<<1)#define RR(x) ((x<<1)|1)struct node{ int cont;}num[50000*4];int deal(int L,int R,int point){ num[point].cont=R-L+1; if(L==R) return 0; int mid=(L+R)/2; deal(L,mid,LL(point)); deal(mid+1,R,RR(point)); return 0; }int update(int L,int R,int left,int right,int point,int k){ if(L==left&&R==right) { if(k==1) num[point].cont=R-L+1; else num[point].cont=0; return 0; } int mid=(L+R)/2; if(num[point].cont==R-L+1) { num[LL(point)].cont=mid-L+1; num[RR(point)].cont=R-mid; } if(num[point].cont==0) { num[LL(point)].cont=0; num[RR(point)].cont=0; } if(right<=mid) { update(L,mid,left,right,LL(point),k); } else if(left>mid) { update(mid+1,R,left,right,RR(point),k); } else { update(L,mid,left,mid,LL(point),k); update(mid+1,R,mid+1,right,RR(point),k); } num[point].cont=num[LL(point)].cont+num[RR(point)].cont; return 0;}int find(int L,int R,int left,int right,int point){ if(L==left&&R==right) return num[point].cont; int sum=0; int mid=(L+R)/2; if(num[point].cont==R-L+1) return right-left+1; if(num[point].cont==0) return 0; if(right<=mid) sum+=find(L,mid,left,right,LL(point)); else if(left>mid) sum+=find(mid+1,R,left,right,RR(point)); else { sum+=find(L,mid,left,mid,LL(point)); sum+=find(mid+1,R,mid+1,right,RR(point)); } return sum;}int main(){ int n,m,k,i,j,T,a,b; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); deal(1,n,1); for(i=1;i<=m;i++) { scanf("%d%d%d",&k,&a,&b); if(k==1) { a+=1; int cont=find(1,n,a,n,1); if(cont==0) printf("Can not put any one.\n"); else { int left,right,mid; int star,end; left=a; right=n; while(left<=right) { mid=(left+right)/2; if(find(1,n,left,mid,1)>0) { right=mid-1; star=mid; } else left=mid+1; } if(cont<=b) { left=a; right=n; while(left<=right) { mid=(left+right)/2; if(find(1,n,mid,right,1)>0) { left=mid+1; end=mid; } else right=mid-1; } //end=right; } else { left=a; right=n; while(left<=right) { mid=(left+right)/2; if(find(1,n,star,mid,1)>=b) { right=mid-1; end=mid; } else left=mid+1; } //end=left; } printf("%d %d\n",star-1,end-1); update(1,n,star,end,1,-1); } } else { printf("%d\n",b-a+1-find(1,n,a+1,b+1,1)); update(1,n,a+1,b+1,1,1); } } printf("\n"); } return 0; }
0 0
- hdu4614 二分+线段树
- 【HDU4614】【线段树】【二分】
- hdu4614 Vases and Flowers(线段树+二分)
- hdu4614(二分查询线段树)
- hdu4614 Vases and Flowers(简单线段树 + 二分)
- Vases and Flowers(hdu4614,线段树+二分查找)
- hdu4614 Vases and Flowers (简单线段树 + 二分)
- hdu4614(二分法+线段树)
- 【线段树专题】hdu4614
- hdu4614 线段树区间更新
- HDU4614【线段树。】【花瓶与插花】
- 线段树之HDU4614 Vases and Flowers
- hdu4614 Vases and Flowers (线段树)
- hdu4614 Vases and Flowers 二分
- hdu4614
- HDU4614
- hdu3564(二分+线段树)
- hdu5217Brackets【线段树,二分】
- 11家PaaS公有云供应商服务功能要点比较
- 分隔符分解字符串
- 一起学习操作系统(1)
- git - 简明指南
- TextSwitcher切换动画
- hdu4614 二分+线段树
- 求质数 之 除余法(C语言描述)
- 蓝桥杯---神奇算式
- ios将Image保存到手机相册
- REST无状态的理解
- MariaDB+Keepalived双主高可用配置MySQL-HA
- 解析Delta Queue数据解析方法
- Stack
- ubuntu install OpenJDK/JRE