POJ 3667 线段树+标记
2016-09-25 17:39
246 查看
自从某次考试写线段树写挂了以后 这是第一次写线段树,,,,,,
这是一个伤心的故事……
题意:
思路:
标记 维护从左到右的最大值 从右到左的最大值 区间内的最大值……
然后就一搞 就出来了
//By SiriusRen #include <cstdio> using namespace std; int n,m,jy,xx,yy,d,D; struct Tree{int lsum,rsum,sum,cover;}tree[222222]; inline int max(int x,int y){return x>y?x:y;} inline int read(){ int x=0;char p=getchar(); while(p<'0'||p>'9')p=getchar(); while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar(); return x; } void build(int l,int r,int pos){ if(l==r){tree[pos].sum=tree[pos].lsum=tree[pos].rsum=1;return;} int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1; build(l,mid,lson),build(mid+1,r,rson); tree[pos].lsum=tree[pos].rsum=tree[pos].sum=tree[lson].sum+tree[rson].sum; } void push_down(int num,int pos){ int lson=pos<<1,rson=pos<<1|1; tree[lson].cover=tree[rson].cover=tree[pos].cover; if(tree[pos].cover==1){ tree[lson].lsum=tree[lson].rsum=tree[lson].sum=num-(num>>1); tree[rson].lsum=tree[rson].rsum=tree[rson].sum=num>>1; } else{ tree[lson].lsum=tree[lson].rsum=tree[lson].sum=0; tree[rson].lsum=tree[rson].rsum=tree[rson].sum=0; } tree[pos].cover=0; } void push_up(int num,int pos){ int lson=pos<<1,rson=pos<<1|1,div=num>>1; tree[pos].lsum=tree[lson].lsum,tree[pos].rsum=tree[rson].rsum; tree[pos].sum=max(max(tree[lson].sum,tree[rson].sum),tree[lson].rsum+tree[rson].lsum); if(tree[lson].lsum==num-div)tree[pos].lsum+=tree[rson].lsum; if(tree[rson].rsum==div)tree[pos].rsum+=tree[lson].rsum; } int query(int l,int r,int pos){ if(l==r)return l; if(tree[pos].cover)push_down(r-l+1,pos); int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1; if(tree[pos].sum>=d){ if(tree[lson].sum>=d)return query(l,mid,lson); if(tree[lson].rsum+tree[rson].lsum>=d)return mid+1-tree[lson].rsum; return query(mid+1,r,rson); } return 0; } void insert(int l,int r,int pos,int id){ if(l>=xx&&r<=yy){ tree[pos].cover=id; tree[pos].lsum=tree[pos].rsum=tree[pos].sum=(id==1?r-l+1:0); return; } int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1,len=r-l+1; if(tree[pos].cover)push_down(len,pos); if(mid<xx)insert(mid+1,r,rson,id); else if(mid>=yy)insert(l,mid,lson,id); else insert(l,mid,lson,id),insert(mid+1,r,rson,id); push_up(len,pos); } int main(){ scanf("%d%d",&n,&m); build(1,n,1); for(int i=1;i<=m;i++){ jy=read(); if(jy==1){ D=read(),d=D; xx=query(1,n,1),yy=xx+D-1; printf("%d\n",xx); if(xx)insert(1,n,1,2); } else{ xx=read(),yy=read(); yy=xx+yy-1; insert(1,n,1,1); } } }
相关文章推荐
- 达内学习笔记-win32开发windows.h文件
- 在VS中用正则表达式查找或替换
- 代码设置Shape和Selector
- Android动画-帧动画&补间动画
- ActivityManagerService启动过程
- linux运维(五)
- Android-滑动删除布局
- 编程练习:同色方块识别问题
- OpenGL学习笔记: 网格剪切
- HDU 5878 I Count Two Three 青岛网络赛
- 内核态和用户态的区别
- R语言绘图功能之强大
- c#@屏@蔽@窗@口@关@闭@按@钮
- [Usaco08Jan&luogu1948] Telephone Lines
- ARC指南1 - strong和weak指针
- java NIO(一)
- PAT 乙级 1002. 写出这个数
- HDU Today2112
- Hibernate的第一个程序
- web服务器的缺陷与解决办法