POJ_3667 线段树+lazy (线段树经典题)
来源:互联网 发布:mac百度搜索历史 编辑:程序博客网 时间:2024/06/08 02:37
这道题的意思是:N个房间(1-n),进行M次操作,1 x :代表第一种操作:向连续的x房间里面住人,如果能住返回第一个房间的号码(如果有多重解,返回最小值),如果不能住,则输出0.
2 X Y:代表第二种操作,将x,x+1...x+y-1的房间清空。
还是看了题解搞定的一道。。。
总体思路:定义 lmax,rmax,amax,代表分别代表最左端最大连续空着的房间数,最右端最大连续空着的房间数,总的最大空着的连续房间数。lazy表示这段区间是否进行过了pushdown操作,-1表示进行过了,0,1分别表示现在这段区间的状态:空还是满的,update操作中找到对应区间后,把这个区间进行lazy标记,然后再pushup,更新之前的结点。query操作,先在结点的左儿子的asum找,如果符合了,进入左儿子query,然后在中间的部分找,如果符合了直接返回值:m-tree[rt<<1].rmax+1。最后在右儿子里面找。每一次找都要先pushdown,把lazy标记去掉,并且向下pushdwn。
下面是ac代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <vector>#include <cstdlib>#define lson rt<<1,l,m#define rson rt<<1|1,m+1,rusing namespace std;const int maxn = 50005;struct Node{ int l,r; int lmax,rmax,amax; int lazy;}tree[8*maxn];int pos;void PushDown(int rt){ int l=tree[rt].l; int r=tree[rt].r; int m=(r+l)>>1; if(tree[rt].lazy!=-1) { tree[rt<<1].lazy=tree[rt<<1|1].lazy=tree[rt].lazy; tree[rt<<1].lmax=tree[rt<<1].rmax=tree[rt<<1].amax=(tree[rt].lazy) ? 0 : (m-l+1); tree[rt<<1|1].lmax=tree[rt<<1|1].rmax=tree[rt<<1|1].amax=(tree[rt].lazy) ? 0:(r-m); tree[rt].lazy=-1; }}void PushUp(int rt){ int ll=tree[rt<<1].r-tree[rt<<1].l+1,rr=tree[rt<<1|1].r-tree[rt<<1|1].l+1; tree[rt].lmax=tree[rt<<1].lmax; tree[rt].rmax=tree[rt<<1|1].rmax; if(ll==tree[rt<<1].lmax) tree[rt].lmax+=tree[rt<<1|1].lmax; if(rr==tree[rt<<1|1].rmax) tree[rt].rmax+=tree[rt<<1].rmax; tree[rt].amax=max(max(tree[rt<<1].amax,tree[rt<<1|1].amax),(tree[rt<<1].rmax+tree[rt<<1|1].lmax));}void Build(int rt,int l,int r){ tree[rt].l=l; tree[rt].r=r; tree[rt].lmax=tree[rt].rmax=tree[rt].amax=(r-l+1); tree[rt].lazy=-1; if(l==r) return; int m=(l+r)>>1; Build(lson); Build(rson);}void query(int rt,int v){ int l=tree[rt].l; int r=tree[rt].r; int m=(l+r)>>1; if(l==r) { pos=l; return; } PushDown(rt); if(tree[rt<<1].amax>=v) query(rt<<1,v); else if(tree[rt<<1].rmax+tree[rt<<1|1].lmax>=v) { pos=m-tree[rt<<1].rmax+1; return; } else query(rt<<1|1,v);}void update(int rt,int c,int s,int e){ int l=tree[rt].l; int r=tree[rt].r; int m=(l+r)>>1; if(l==s && r==e) { tree[rt].lmax=tree[rt].rmax=tree[rt].amax= c ? 0:(r-l+1); tree[rt].lazy=c; return; } PushDown(rt); if(e<=m) update(rt<<1,c,s,e); else if(s>m) update(rt<<1|1,c,s,e); else { update(rt<<1,c,s,m); update(rt<<1|1,c,m+1,e); } PushUp(rt);}int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { Build(1,1,n); int k,x,y; while(m--) { scanf("%d",&k); if(k==1) { scanf("%d",&x); if(tree[1].amax<x) printf("0\n"); else { query(1,x); printf("%d\n",pos); update(1,1,pos,pos+x-1); } } else { scanf("%d%d",&x,&y); update(1,0,x,x+y-1); } } } return 0;}
0 0
- POJ_3667 线段树+lazy (线段树经典题)
- poj_3667线段树区间合并
- pku3468 线段树lazy
- 线段树lazy操作
- JuQueen(线段树 lazy)
- 【例题】【线段树】lazy
- 线段树Lazy-tag
- 线段树--lazy思想
- HDU1698(线段树LAZY)
- 线段树lazy标记
- CodeForces877E 线段树lazy
- poj 3468 A Simple Problem with Integers(线段树,lazy思想 经典题)
- 线段填色(线段树LAZY)
- POJ2777(线段树区间更新+LAZY)
- 线段树多lazy-tag(两个)
- poj1436(线段树lazy标记)
- 还教室(线段树lazy标记)
- 线段树(lazy算法+离散化)
- Qtcreator中文输入法不能使用问题
- WEB界面客制化之采购申请审批界面(改OAF的VO.XML文件-上传-重启应用-个性化添加栏位)
- javascript的fn方法
- GNU-makefle (一) 基本介绍
- 黑马程序员-------java基础------多线程
- POJ_3667 线段树+lazy (线段树经典题)
- mongoDB的基本操作以及数据的导入导出,备份和恢复
- 测试感想
- CF 479D Long Jumps
- UVA - 10066 The Twin Towers(dp+最大公共子序列)
- ThinkPHP教程--8--之配置格式
- VIM 标签页 (tab)
- Aromafm移植到Android recovery以开发GUI的实现
- 第11周上机实践项目2——求最大公约数