线段树典型例题--poj3667 hotel
2012-07-23 17:22
281 查看
题目很像内存分配。
线段树维护这样几个量:
col:节点的颜色(0--没有覆盖,1--全覆盖,-1--有多种颜色)
dl:从左边开始的最长连续段
dr:从右边开始的最长连续段
dm:节点中的最长连续段
dp:节点中最长连续段的开始位置
具体见代码:
线段树维护这样几个量:
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 ,dr ,dm ,dp ,col ,l ,r ; bool pp ; 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); } } }
相关文章推荐
- 线段树典型例题--poj2828
- POJ3667——线段树区间合并(未搞透)——Hotel
- poj3667 Hotel(线段树)
- 【poj3667】【线段树】Hotel
- 线段树典型例题--poj3277
- 浅谈线段树 (例题:[USACO08FEB]酒店Hotel)By cellur925
- [POJ3667]Hotel(线段树,区间合并,重写)
- 线段树典型例题--poj2777
- [POJ3667]Hotel(线段树)
- 【POJ3667】Hotel-线段树
- 【线段树区间合并】POJ3667-Hotel
- 【POJ3667】Hotel(线段树)
- poj3667 Hotel (线段树--区间合并)转自网络【2】
- 【随便做做|线段树】POJ3667 Hotel
- poj3667 Hotel (线段树--区间合并)转自网络
- poj3667---Hotel 线段树区间合并,区间更新
- Hotel---poj3667(线段树区间问题)
- [线段树]poj3667 Hotel(区间合并、更新、延迟/懒惰标记
- [POJ3667]Hotel(线段树,区间合并)
- 线段树 poj3667 Hotel