poj 3667 最長空白段+查詢最左連續段

Hotel


大體分析:

   題意:從最左找連續空間,是否能找到。
   解法:同poj1823。
   //是1823的加強版,但是提交記錄也是呵呵了。
   //多的一個操作就是查詢操作了。

具體分析

  更新操作同poj1823
  查詢操作:
           1. 先判斷是都存在
           2. 如果存在,左兒子中有就遞歸找左兒子
           3. 如果左兒子的有連續+有兒子的左連續空間有,那就返回位置
           4. 否則,遞歸尋找右兒子
  //線段樹真是奇妙,很多更新、查詢操作都很巧妙

參考代碼

  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 201000+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,rsum,msum; 
  32.     int flag; 
  33.     int mid(){ 
  34.         return (l+r)>>1
  35.     } 
  36.     void init(){ 
  37.         lsum=rsum=msum=(r-l+1)*flag; 
  38.     } 
  39. }tree[maxn*4]; 
  40. void build(int rt,int l,int r){ 
  41.     tree[rt].l=l,tree[rt].r=r,tree[rt].flag=1
  42.     tree[rt].init(); 
  43.     if(l==r)return
  44.     int mid=tree[rt].mid(); 
  45.     build(LL(rt),l,mid),build(RR(rt),mid+1,r); 
  46. void update(int rt,int l,int r,int flag){ 
  47.     if(l<=tree[rt].l&&r>=tree[rt].r){ 
  48.         tree[rt].flag=flag;tree[rt].init();return
  49.     } 
  50.     if(tree[rt].flag!=-1){ 
  51.         tree[LL(rt)].flag=tree[RR(rt)].flag=tree[rt].flag; 
  52.         tree[LL(rt)].init();tree[RR(rt)].init();tree[rt].flag=-1
  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 query(int rt,int l,int r,int w) 
  66.     if(l==r)return l; 
  67.     if(tree[rt].flag!=-1){ 
  68.         tree[LL(rt)].flag=tree[RR(rt)].flag=tree[rt].flag; 
  69.         tree[LL(rt)].init();tree[RR(rt)].init();tree[rt].flag=-1
  70.     } 
  71.     int mid=tree[rt].mid(); 
  72.     if(tree[LL(rt)].msum>=w) return query(LL(rt),l,mid,w); 
  73.     else if(tree[LL(rt)].rsum+tree[RR(rt)].lsum>=w)return mid-tree[LL(rt)].rsum+1
  74.     else return query(RR(rt),mid+1,r,w); 
  75. int main() 
  76. #ifndef ONLINE_JUDGE 
  77.      freopen("in.txt","r",stdin); 
  78.      //freopen("out.txt","w",stdout); 
  79. #endif 
  80.     int n,m; 
  81.     while(scanf("%d%d",&n,&m)!=EOF) 
  82.     { 
  83.         build(1,1,n); 
  84.         int i; 
  85.         rep(i,m){ 
  86.             int temp,x,y; 
  87.             scanf("%d",&temp); 
  88.             if(temp==1){ 
  89.                 scanf("%d",&x); 
  90.                 if(tree[1].msum<x)printf("%d\n",0); 
  91.                 else { 
  92.                     int be=query(1,1,n,x); 
  93.                     printf("%d\n",be); 
  94.                     update(1,be,be+x-1,0); 
  95.                 } 
  96.             } 
  97.             else
  98.                 scanf("%d%d",&x,&y); 
  99.                 update(1,x,x+y-1,1); 
  100.             } 
  101.         } 
  102.     } 
  103.     return 0
  104. }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章