7.8 MHDU 4614Vases and Flowers
来源:互联网 发布:linux mv移动文件夹 编辑:程序博客网 时间:2024/05/24 01:20
题意:Alice有许多花要插到花瓶中,每个花瓶只能插一枝花,有以下几种操作:
1.清空目标区间内所有花瓶。
2.给目标区间插上x支花,从首个空的花瓶开始插花。
3.询问目标区间有多少支花。
思路:首先要用到区间赋值的线段树,清空花瓶的过程可以直接完美模拟,那么插花怎么办呢?这时要用到二分来寻找插花的起点和终点,对于能插完x支花和不能插完x支花的情况还要分类讨论。
代码:
#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn=50001,logn=20;int n,m;int setv[maxn*logn],sumv[maxn*logn],_qL,_qR,_Value,_sum;//维护信息void maintain(int o, int L, int R){ int lc = o*2, rc = o*2+1; if(R > L){ sumv[o] = sumv[lc] + sumv[rc]; } if(setv[o] >= 0) sumv[o] = (R-L+1) * setv[o];}//标记传递void pushdown(int o){ int lc = o*2, rc = o*2+1; if(setv[o] >= 0){//-1表示没有标记过节点 setv[lc] = setv[rc] = setv[o]; setv[o] = -1;//清除本节点的标记 }}void update(int o, int L, int R){ int lc = o*2, rc = o*2+1; if(_qL <= L && R <= _qR) setv[o] = _Value; else{ pushdown(o); int M = (L + R) / 2; if(_qL <= M) update(lc, L, M); else maintain(lc, L, M); if(_qR > M) update(rc, M+1, R); else maintain(rc, M+1, R); } maintain(o, L, R);}void query(int o, int L, int R){ if(setv[o] >= 0){//递归边界1:有set标记 _sum += setv[o] * (min(R, _qR) - max(L, _qL) + 1); } else if(_qL <= L && R <= _qR){//递归边界2:边界区间,此区间没有收到set影响 _sum += sumv[o]; } else{//递归统计 int M = (L + R) / 2; if(_qL <= M) query(o*2, L, M); if(_qR > M) query(o*2+1, M+1, R); }}void Update(int l,int r,int v){ _qL=l; _qR=r; _Value=v; update(1,1,n);}int Query(int l,int r){ _sum=0; _qL=l; _qR=r; query(1,1,n); return _sum;}void init(){ memset(sumv,0,sizeof(sumv)); memset(setv,-1,sizeof(setv)); setv[0]=1;}bool C1(int ept1,int l,int r){ int ept2=r-l+1-Query(l,r); return ept2<ept1;}bool C2(int ept1,int l,int r){ int ept2=r-l+1-Query(l,r); return ept2<ept1;}bool C3(int amt,int l,int r){ int ept=r-l+1-Query(l,r); return ept>=amt;}bool C4(int amt,int l,int r){ int ept=r-l+1-Query(l,r); return ept>=amt;}int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); init(); for(int i=0;i<m;i++){ int op,l,amt,r; scanf("%d%d",&op,&l);l++; if(op==1){ scanf("%d",&amt); int used=Query(l,n);int ept=n-l+1-used; if(ept==0){ printf("Can not put any one.\n"); continue; } if(ept<amt){ //二分找使得ept-1的下界和上界。 int l1,r1,mid1,l2,r2,mid2; l1=l; r1=n+1; while(r1-l1>1){ mid1=(l1+r1)/2; if(C1(ept,l,mid1))l1=mid1; else r1=mid1; } if(r1>n||Query(r1,r1)==1) r1--; l2=l; r2=r1+1; while(r2-l2>1){ mid2=(l2+r2)/2; if(C2(ept,mid2,r1))r2=mid2; else l2=mid2; } printf("%d %d\n",l2-1,r1-1); Update(l2,r1,1); } else{ //二分找使得ept恰好等于amt的点,再找在ept等于amt时的上界。 int l1,r1,mid1,l2,r2,mid2; l1=l-1; r1=n+1; while(r1-l1>1){ mid1=(l1+r1)/2; if(C3(amt,l,mid1))r1=mid1; else l1=mid1; } if(r1>n||Query(r1,r1)==1) r1--; l2=l-1; r2=r1+1; while(r2-l2>1){ mid2=(l2+r2)/2; if(C4(amt,mid2,r1)) l2=mid2; else r2=mid2; } printf("%d %d\n",l2-1,r1-1); Update(l2,r1,1); } } else{ scanf("%d",&r);r++; printf("%d\n",Query(l,r)); Update(l,r,0); } } printf("\n"); } return 0;}
0 0
- 7.8 MHDU 4614Vases 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
- HDOJ 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(线段树)
- [Lintcode]Segment Tree Build
- 原码, 反码, 补码 详解
- HTML5系列之启动篇--语义化标签
- MTK codegen.dws文件---GPIO口的定制
- JVM之内存分配与回收策略
- 7.8 MHDU 4614Vases and Flowers
- 个人总结1
- Android——ContentProvide 内容提供者+四大组件之三
- SQL语句
- Spring实现Websocket
- cloudera-scm-agent 启动失败 'Unable to create the pidfile'问题解决
- HDU 5877 Weak Pair 2016 ACM/ICPC Asia Regional Dalian Online(树状数组+离散化)
- Linux 如何禁止用户登录
- 单链表逆转