zoukankan      html  css  js  c++  java
  • 【洛谷】 P2894 [USACO08FEB]Hotel G (线段树)

    洛谷 P2894 [USACO08FEB]Hotel G

    • 题意\(n\)个房间,\(m\)个操作,每次有2中操作,操作1为在\([1,n]\)中查询长度为\(x\)的连续空房间,输出最小的最左端的房间id,然后占用这\(x\)个房间,操作2使得\([x,x+y-1]\)这么多房间空出来.

    • 题解:连续的区间和问题,经典用线段树来解决,即pushup的时候维护左儿子的区间右端点连续情况和右儿子的区间左端点的连续情况,这样就可以保证每次维护的连续情况。

    • 代码

      #include <bits/stdc++.h>
      
      using namespace std;
      const int N=1e6+10;
      const int mod=1e9+7;
      #define ll long long
      #define pb push_back
      
      int n,m;
      
      struct Node{
          int l,r;
          int tag;
          int lmx,rmx;
          int mx;
      }tr[N<<4];
      
      void push_up(int u){
          if(tr[u<<1].mx==tr[u<<1].r-tr[u<<1].l+1) tr[u].lmx=tr[u<<1].mx+tr[u<<1|1].lmx;
          else tr[u].lmx=tr[u<<1].lmx;
      
          if(tr[u<<1|1].mx==tr[u<<1|1].r-tr[u<<1|1].l+1) tr[u].rmx=tr[u<<1|1].mx+tr[u<<1].rmx;
          else tr[u].rmx=tr[u<<1|1].rmx;
      
          tr[u].mx=max({tr[u<<1].mx,tr[u<<1|1].mx,tr[u<<1].rmx+tr[u<<1|1].lmx});
      }
      
      void push_down(int u){
          if(tr[u].tag==1){
              tr[u<<1].lmx=tr[u<<1].rmx=tr[u<<1].mx=tr[u<<1].r-tr[u<<1].l+1;
              tr[u<<1].tag=1;
              tr[u<<1|1].lmx=tr[u<<1|1].rmx=tr[u<<1|1].mx=tr[u<<1|1].r-tr[u<<1|1].l+1;
              tr[u<<1|1].tag=1;
          }
          if(tr[u].tag==0){
              tr[u<<1].lmx=tr[u<<1].rmx=tr[u<<1].mx=0;
              tr[u<<1].tag=0;
              tr[u<<1|1].lmx=tr[u<<1|1].rmx=tr[u<<1|1].mx=0;
              tr[u<<1|1].tag=0;
          }
          tr[u].tag=-1;
      }
      
      void build(int u,int l,int r){
          if(l==r){
              tr[u]={l,r,-1,1,1,1};
              return;
          }
          tr[u]={l,r,-1,0,0,0};
          int mid=(l+r)>>1;
          build(u<<1,l,mid);
          build(u<<1|1,mid+1,r);
          push_up(u);
      }
      
      void update(int u,int L,int R,int f){
          if(tr[u].l>=L && tr[u].r<=R){
              if(!f){     //填上
                  tr[u].mx=0;
                  tr[u].lmx=tr[u].rmx=0;
                  tr[u].tag=0;
              }
              else{     //清空
                  tr[u].mx=tr[u].r-tr[u].l+1;
                  tr[u].lmx=tr[u].rmx=tr[u].mx;
                  tr[u].tag=1;
              }
              return;
          }
          push_down(u);
          int mid=(tr[u].l+tr[u].r)>>1;
          if(L<=mid) update(u<<1,L,R,f);
          if(R>mid) update(u<<1|1,L,R,f);
          push_up(u);
      }
      
      int query(int u,int L,int R,int x){
          if(L==R) return L;
          push_down(u);
          int mid=(L+R)>>1;
          if(tr[u<<1].mx>=x) return query(u<<1,L,mid,x);
          else if(tr[u<<1].rmx+tr[u<<1|1].lmx>=x) return mid-tr[u<<1].rmx+1;
          else return query(u<<1|1,mid+1,R,x);
      }
      
      int main(){
          scanf("%d %d",&n,&m);
      
          build(1,1,n);
      
          while(m--){
              int op;
              scanf("%d",&op);
              if(op==1){
                  int x;
                  scanf("%d",&x);
                  if(tr[1].mx<x){
                      puts("0");
                      continue;
                  }
                  int ans=query(1,1,n,x);
                  printf("%d\n",ans);
                  update(1,ans,ans+x-1,0);
              }
              else{
                  int l,r;
                  scanf("%d %d",&l,&r);
                  update(1,l,l+r-1,1);
              }
          }
          
          return 0;
      }
      
      
  • 相关阅读:
    灰度图转换
    OGRE分析之文件系统 (1)
    屏幕截图
    [GP]template必须定义于头文件中
    OGRE分析之设计模式
    ON_COMMAND_RANGE和ON_UPDATE_COMMAND_UI_RANGE
    使用SkinMagic Toolkit美化界面(II)
    Single Sign On for Windows and Linux
    "C compiler cannot create executables"
    How to Create a First C Program on Linux
  • 原文地址:https://www.cnblogs.com/lr599909928/p/15590643.html
Copyright © 2011-2022 走看看