poj 1823 最長空白段

Hotel


大體分析:

題意:最長的空白段,操作段的加入和刪除操作
解法:線段樹+lazy標記

具體操作:

> * 線段樹維護,左邊最長連續,右邊最長連續、中間最長連續,因爲之後邊上的連續段對父親的段纔有影響
> * 添加Lazy標記纔會保證時間~
> * 轉移比較難理解
> * 符合poj 的一貫風格,空間一定要開的足夠大(這樣有意思嘛)
> * lazy標記的作用就是需要是有子樹的時候才更新就好了。

代碼c++

  1. #include<iostream> 
  2. #include<cstring> 
  3. #include <algorithm> 
  4. #include<cstdlib> 
  5. #include<vector> 
  6. #include<cmath> 
  7. #include<stdlib.h> 
  8. #include<iomanip> 
  9. #include<list> 
  10. #include<deque> 
  11. #include<map> 
  12. #include <stdio.h> 
  13. #include <queue> 
  14.  
  15. #define maxn 160000+5 
  16.  
  17. #define inf 0x3f3f3f3f 
  18.   #define INF 0x3FFFFFFFFFFFFFFFLL 
  19. #define rep(i,n) for(i=0;i<n;i++) 
  20.  #define reP(i,n) for(i=1;i<=n;i++) 
  21.  
  22. #define ull unsigned long long 
  23.  #define ll long long 
  24. #define LL(x) x<<1 
  25.  #define RR(x) x<<1|1 
  26.  
  27. #define cle(a) memset(a,0,sizeof(a)) 
  28.  
  29. using namespace std; 
  30. struct node{ 
  31.     int l,r,lsum,msum,rsum; 
  32.     int flag;//1->全部可以入住 0->全部不可以入住 
  33.     int mid(){ 
  34.         return (l+r)>>1
  35.     } 
  36.     void init(){ 
  37.         lsum=msum=rsum=(r-l+1)*flag; 
  38.     } 
  39. }tree[maxn*2]; 
  40. void build(int rt,int l,int r){ 
  41.     tree[rt].l=l,tree[rt].r=r,tree[rt].flag=1,tree[rt].init(); 
  42.     if(l==r)return
  43.     int mid=tree[rt].mid(); 
  44.     build(LL(rt),l,mid),build(RR(rt),mid+1,r); 
  45. void update(int rt,int l,int r,int flag){ 
  46.     if(l<=tree[rt].l&&r>=tree[rt].r){ 
  47.         tree[rt].flag=flag;tree[rt].init();return
  48.     } 
  49.     if(tree[rt].flag!=-1
  50.     { 
  51.         tree[LL(rt)].flag=tree[RR(rt)].flag=tree[rt].flag; 
  52.         tree[rt].flag=-1;tree[LL(rt)].init();tree[RR(rt)].init(); 
  53.     } 
  54.     int mid=tree[rt].mid(); 
  55.     if(r<=mid)update(LL(rt),l,r,flag); 
  56.     else if(l>mid)update(RR(rt),l,r,flag); 
  57.     else { 
  58.         update(LL(rt),l,mid,flag),update(RR(rt),mid+1,r,flag); 
  59.     } 
  60.     if(tree[LL(rt)].lsum==tree[LL(rt)].r-tree[LL(rt)].l+1)tree[rt].lsum=tree[LL(rt)].lsum+tree[RR(rt)].lsum; 
  61.     else tree[rt].lsum=tree[LL(rt)].lsum; 
  62.     if(tree[RR(rt)].rsum==tree[RR(rt)].r-tree[RR(rt)].l+1)tree[rt].rsum=tree[LL(rt)].rsum+tree[RR(rt)].rsum; 
  63.     else tree[rt].rsum=tree[RR(rt)].rsum; 
  64.     tree[rt].msum=max(max(tree[LL(rt)].msum,tree[RR(rt)].msum),tree[LL(rt)].rsum+tree[RR(rt)].lsum); 
  65. int main() 
  66. #ifndef ONLINE_JUDGE 
  67.      freopen("in.txt","r",stdin); 
  68.      //freopen("out.txt","w",stdout); 
  69. #endif 
  70.     int n,p; 
  71.     while(scanf("%d%d",&n,&p)!=EOF){ 
  72.         int type,x,y; 
  73.         build(1,1,n); 
  74.         int i; 
  75.         rep(i,p){ 
  76.             scanf("%d",&type); 
  77.             if(type==3){ 
  78.                 printf("%d\n",tree[1].msum); 
  79.             } 
  80.             else
  81.                 scanf("%d%d",&x,&y); 
  82.                 if(type==1)//入住 
  83.                 { 
  84.                     update(1,x,x+y-1,0); 
  85.                 } 
  86.                 else update(1,x,x+y-1,1); 
  87.             } 
  88.         } 
  89.     } 
  90.     return 0
  91. }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章