博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[题解](线段树最大连续子段和)POJ_3667_Hotel
阅读量:5040 次
发布时间:2019-06-12

本文共 2508 字,大约阅读时间需要 8 分钟。

题意:1.求一个最靠左的长x的区间全部为0,并修改为1,输出这个区间的左端点

2.修改一个区间为0

实际上是维护最大连续子段和,原来也写过

大概需要维护一个左/右最大子段和,当前这段最大子段长,再维护一个lazytag

#include
#include
#include
#define mid (l+r>>1)#define ls x<<1#define rs x<<1|1using namespace std;const int maxn=50009;struct node{ int l,r,mx,tg;//0全空,1全满,-1没有}t[maxn<<2];//inline void upd(int x,int l,int r){// t[x].l=t[ls].l;// t[x].r=t[rs].r;//// if(t[ls].l==mid-l+1)t[x].l+=t[rs].l;//// if(t[rs].r==r-mid)t[x].r+=t[ls].r;// if(t[ls].l==(r-l+1-(r-l+1)/2))t[x].l+=t[rs].l;// if(t[rs].r==(r-l+1)/2)t[x].r+=t[ls].r;// t[x].mx=max(max(t[ls].mx,t[rs].mx),t[ls].r+t[rs].l);//}//inline void pushdown(int x,int l,int r){// if(t[x].tg!=-1){// t[ls].tg=t[rs].tg=t[x].tg;// t[ls].l=t[ls].r=t[ls].mx=(r-l+1-(r-l+1)/2)*t[x].tg;// t[rs].l=t[rs].r=t[rs].mx=(r-l+1)/2*t[x].tg;//// if(t[x].tg==0){//// t[ls].l=t[ls].r=t[ls].mx=mid-l+1;//// t[rs].l=t[rs].r=t[rs].mx=r-mid; //// }//// else{//// t[ls].l=t[ls].r=t[ls].mx=0;//// t[rs].l=t[rs].r=t[rs].mx=0;//// }// t[x].tg=-1;// }//}inline void pushdown(int x,int len){ if(t[x].tg!=-1){ t[ls].tg=t[rs].tg=t[x].tg; t[ls].mx=t[ls].l=t[ls].r=t[x].tg*(len-(len>>1)); t[rs].mx=t[rs].l=t[rs].r=t[x].tg*(len>>1); t[x].tg=-1; }}inline void upd(int x,int len){ t[x].l=t[ls].l; t[x].r=t[rs].r; if(t[x].l==len-(len>>1))t[x].l+=t[rs].l; if(t[x].r==(len>>1))t[x].r+=t[ls].r; t[x].mx=max(max(t[ls].mx,t[rs].mx),t[ls].r+t[rs].l);}void build(int x,int l,int r){ t[x].l=t[x].r=t[x].mx=r-l+1;t[x].tg=-1; if(l==r)return; build(ls,l,mid);build(rs,mid+1,r);}void change(int x,int l,int r,int L,int R,int k){ if(L<=l && r<=R){ t[x].l=t[x].r=t[x].mx= k==0?0:r-l+1; t[x].tg=k; return; }// pushdown(x,l,r); pushdown(x,r-l+1); if(L<=mid)change(ls,l,mid,L,R,k); if(R>mid)change(rs,mid+1,r,L,R,k);// upd(x,l,r); upd(x,r-l+1);}int query(int x,int l,int r,int k){ if(l==r)return 1;// pushdown(x,l,r); pushdown(x,r-l+1); if(t[ls].mx>=k)return query(ls,l,mid,k); else if(t[ls].r+t[rs].l>=k)return mid-t[ls].r+1; else return query(rs,mid+1,r,k);}int n,m;int main(){ scanf("%d%d",&n,&m); build(1,1,n); for(int i=1,op,x,y;i<=m;i++){ scanf("%d",&op); if(op==1){ scanf("%d",&x); if(t[1].mx

 

转载于:https://www.cnblogs.com/superminivan/p/11025449.html

你可能感兴趣的文章
全面整理的C++面试题
查看>>
Web前端从入门到精通-9 css简介——盒模型1
查看>>
Activity和Fragment生命周期对比
查看>>
OAuth和OpenID的区别
查看>>
android 分辨率自适应
查看>>
查找 EXC_BAD_ACCESS 问题根源的方法
查看>>
国外媒体推荐的5款当地Passbook通行证制作工具
查看>>
日常报错
查看>>
list-style-type -- 定义列表样式
查看>>
hibernate生成表时,有的表可以生成,有的却不可以 2014-03-21 21:28 244人阅读 ...
查看>>
mysql-1045(28000)错误
查看>>
Ubuntu 编译出现 ISO C++ 2011 不支持的解决办法
查看>>
1.jstl c 标签实现判断功能
查看>>
Linux 常用命令——cat, tac, nl, more, less, head, tail, od
查看>>
超详细的Guava RateLimiter限流原理解析
查看>>
VueJS ElementUI el-table 的 formatter 和 scope template 不能同时存在
查看>>
Halcon一日一练:图像拼接技术
查看>>
Swift - RotateView
查看>>
iOS设计模式 - 中介者
查看>>
centos jdk 下载
查看>>