线段树典型例题--poj3667 hotel
来源:互联网 发布:怎么把淘宝店做起来 编辑:程序博客网 时间:2024/05/29 10:36
题目很像内存分配。
线段树维护这样几个量:
col:节点的颜色(0--没有覆盖,1--全覆盖,-1--有多种颜色)
dl:从左边开始的最长连续段
dr:从右边开始的最长连续段
dm:节点中的最长连续段
dp:节点中最长连续段的开始位置
具体见代码:
#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <algorithm>using namespace std;const int N=400000;int dl[N],dr[N],dm[N],dp[N],col[N],l[N],r[N];bool pp[N];int n,m;void build(int i,int ll,int rr){ l[i]=ll;r[i]=rr; dl[i]=dr[i]=dm[i]=r[i]-l[i]+1; col[i]=0; dp[i]=l[i]; pp[i]=false; if (l[i]==r[i]) return; int mid=(l[i]+r[i])/2; build(i*2,l[i],mid); build(i*2+1,mid+1,r[i]);}void down(int i){ if (!pp[i]) return; col[i*2]=col[i*2+1]=col[i]; if (col[i]==0) { dl[i*2]=dr[i*2]=dm[i*2]=r[i*2]-l[i*2]+1; dp[i*2]=l[i*2]; dl[i*2+1]=dr[i*2+1]=dm[i*2+1]=r[i*2+1]-l[i*2+1]+1; dp[i*2+1]=l[i*2+1]; } else { dl[i*2]=dr[i*2]=dm[i*2]=0; dl[i*2+1]=dr[i*2+1]=dm[i*2+1]=0; } pp[i]=false; pp[i*2]=true;pp[i*2+1]=true;}int find(int i,int k){ if (l[i]==r[i]) { if (dm[i]>=k) return dp[i]; else return 0; } if (dm[i]>=k) { down(i); if (dm[i*2]>=k) return find(i*2,k); else if (dr[i*2]+dl[i*2+1]>=k) return r[i*2]-dr[i*2]+1; else if (dm[i*2+1]>=k) return find(i*2+1,k); } else return 0;}void update(int i){ if (col[i*2]==0 || col[i*2+1]==0) { if (col[i*2+1]==col[i*2]) col[i]=0; else col[i]=-1; if (col[i*2]==0) dl[i]=dl[i*2]+dl[i*2+1]; else dl[i]=dl[i*2]; if (col[i*2+1]==0) dr[i]=dr[i*2]+dr[i*2+1]; else dr[i]=dr[i*2+1]; } else if (col[i*2]==-1 || col[i*2+1]==-1) { col[i]=-1; dl[i]=dl[i*2]; dr[i]=dr[i*2+1]; } else if (col[i*2]==1 && col[i*2+1]==1) { col[i]=1; dl[i]=dr[i]=0; } dm[i]=dm[i*2];dp[i]=dp[i*2]; if (dr[i*2]+dl[i*2+1]>dm[i]) { dm[i]=dr[i*2]+dl[i*2+1]; dp[i]=r[i*2]-dr[i*2]+1; } else if (dr[i*2]+dl[i*2+1]==dm[i] && r[i*2]-dr[i*2]+1<dp[i]) dp[i]=r[i*2]-dr[i*2]+1; if (dm[i*2+1]>dm[i]) { dm[i]=dm[i*2+1]; dp[i]=dp[i*2+1]; } else if (dm[i*2+1]==dm[i] && dp[i*2+1]<dp[i]) dp[i]=dp[i*2+1];}void change(int i,int x,int y,int cc){ if (x<=l[i] && y>=r[i]) { col[i]=cc; if (col[i]==0) { dl[i]=dr[i]=dm[i]=r[i]-l[i]+1; dp[i]=l[i]; } else dl[i]=dr[i]=dm[i]=0; pp[i]=true; return; } down(i); int mid=(l[i]+r[i])/2; if (x<=mid) change(i*2,x,y,cc); if (y>mid) change(i*2+1,x,y,cc); update(i);}int main(){ int i,j,k,d; freopen("in","r",stdin); scanf("%d%d",&n,&m); build(1,1,n); for (i=1;i<=m;i++) { scanf("%d",&j); if (j==1) { scanf("%d",&d); k=find(1,d); printf("%d\n",k); if (k>0) change(1,k,k+d-1,1); } else { scanf("%d%d",&k,&d); change(1,k,k+d-1,0); } }}
- 线段树典型例题--poj3667 hotel
- 【poj3667】【线段树】Hotel
- 【线段树】Hotel POJ3667
- POJ3667 Hotel(线段树)
- 线段树 poj3667 Hotel
- 【POJ3667】Hotel-线段树
- #POJ3667#Hotel(线段树)
- poj3667 Hotel(线段树)
- POJ3667——Hotel(线段树)
- poj3667 Hotel (线段树区间合并)
- POJ3667:Hotel(线段树区间合并)
- poj3667 Hotel 线段树 区间合并
- POJ3667-Hotel-线段树区间合并(模板)
- 【随便做做|线段树】POJ3667 Hotel
- poj3667-Hotel 线段树区间合并
- poj3667 Hotel (线段树+区间合并)
- poj3667 Hotel (线段树--区间合并)转自网络
- poj3667 Hotel 线段树延迟更新 区间合并
- A股每天1500人销户
- Commons net实现 FTP上传下载
- unix网络编程 学习笔记(精华)
- 一个简单的NT驱动之驱动入口函数(DriverEntry)
- MM问我$100W 的种子期投资且已到账,该如何组建公司及团队
- 线段树典型例题--poj3667 hotel
- poj 2777 Count Color
- 深入剖析Service特性
- Android中处理崩溃异常
- wsgi 介绍
- ubuntu 解压命令
- Linux内存屏障
- 只有 DBA 才能导入由其他 DBA 导出的文件
- 缺失值添加帖子汇总