zoukankan      html  css  js  c++  java
  • Hotel

    poj3667:http://poj.org/problem?id=3667

    题目大意:Hotel有N(1 ≤ N ≤ 50,000)间rooms,并且所有的rooms都是连续排列在同一边,groups需要check in 房间,要求房间的编号为连续的r..r+Di-1并且r是最小的;visitors同样可能check out,并且他们每次check out都是编号为Xi ..Xi +Di-1 (1 ≤ Xi ≤ N-Di+1)的房间,题目的输入有两种样式:
        1  a     :  groups需要check in  a间编号连续的房间
        2  a   b : visitors  check out 房间,其中房间编号是 a…a+b-1要求对于每次request,输出为groups分配数目为a的房间中编号最小的房间编号
    题解:用 线段树维护区间的连续最大值,最大左连续,最大右连续。查询时,如果当前节点的sum值大等于val,则看该区间的左连续,若左连续大等于val,直接返回left;否则,看左二子,如果左儿子的sum值大于等于val,则进入左儿子进行查询,如果不满足,再看左儿子的右连续+右儿子的左连续是否大等于val,若大于则直接返回左儿子右连续的起点值,否则进入右儿子进行查询。否则,返回0.如果返回的不是0,就进行区间更新。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<algorithm>
      5 using namespace std;
      6 int u,v,w;
      7 int n,m;
      8 struct Node{
      9     int left;
     10     int right;
     11     int lsum,rsum,sum;
     12     int lazy;
     13 }node[50002*4];
     14  void build(int l,int r,int idx){
     15      node[idx].left=l;
     16      node[idx].right=r;
     17      node[idx].lazy=0;//lazy标记 
     18      if(l==r){
     19          node[idx].sum=node[idx].lsum=node[idx].rsum=1;
     20          return;
     21      }
     22      int mid=(l+r)/2;
     23      build(l,mid,idx<<1);
     24      build(mid+1,r,idx<<1|1);
     25      node[idx].sum=node[idx].lsum=node[idx].rsum=r-l+1;
     26 }
     27 void pushup(int idx){
     28    if(node[idx<<1].lsum==node[idx<<1].right-node[idx<<1].left+1)
     29         node[idx].lsum=node[idx<<1].lsum+node[idx<<1|1].lsum;
     30     else
     31         node[idx].lsum=node[idx<<1].lsum;
     32    if(node[idx<<1|1].rsum==node[idx<<1|1].right-node[idx<<1|1].left+1)
     33         node[idx].rsum=node[idx<<1].rsum+node[idx<<1|1].rsum;
     34      else
     35     node[idx].rsum=node[idx<<1|1].rsum;
     36     node[idx].sum=node[idx<<1].rsum+node[idx<<1|1].lsum;
     37     node[idx].sum=max(node[idx<<1].sum,max(node[idx].sum,node[idx<<1|1].sum));
     38 }
     39 void pushdown(int idx){
     40         if(node[idx].lazy==1){
     41         node[idx<<1].sum=node[idx<<1|1].sum=0;
     42         node[idx<<1].lsum=node[idx<<1].rsum=0;
     43         node[idx<<1|1].lsum=node[idx<<1|1].rsum=0;
     44         node[idx<<1].lazy=node[idx<<1|1].lazy=1;//很重要,开始忘记往下传递问题 
     45         node[idx].lazy=0;
     46       }
     47     if(node[idx].lazy==2){
     48         node[idx<<1].lsum=node[idx<<1].rsum=node[idx<<1].sum=node[idx<<1].right-node[idx<<1].left+1;
     49         node[idx<<1|1].lsum=node[idx<<1|1].rsum=node[idx<<1|1].sum=node[idx<<1|1].right-node[idx<<1|1].left+1;
     50         node[idx<<1].lazy=node[idx<<1|1].lazy=2;
     51         node[idx].lazy=0;
     52       }
     53 }
     54 void update1(int l,int r,int val,int idx){
     55     if(node[idx].left==l&&node[idx].right==r&&val==1){
     56         node[idx].sum=0;
     57         node[idx].lsum=node[idx].rsum=0;    
     58         node[idx].lazy=1;
     59         return;
     60     }
     61     if(node[idx].left==l&&node[idx].right==r&&val==0){
     62         node[idx].sum=node[idx].right-node[idx].left+1;
     63         node[idx].lsum=node[idx].rsum=node[idx].right-node[idx].left+1;
     64         node[idx].lazy=2;
     65         return;
     66     }
     67        pushdown(idx);
     68       int mid=(node[idx].right+node[idx].left)/2;
     69       if(mid>=r)update1(l,r,val,idx<<1);
     70       else if(mid<l)update1(l,r,val,idx<<1|1);
     71       else{
     72           update1(l,mid,val,idx<<1);
     73           update1(mid+1,r,val,idx<<1|1);
     74       }
     75       pushup(idx);
     76 }
     77 int update2(int val,int idx){
     78     if(node[idx].sum>=val){
     79         pushdown(idx);
     80         if(node[idx].lsum>=val){
     81            return node[idx].left;
     82         }
     83         else if(node[idx<<1].sum>=val)return update2(val,idx<<1);
     84         else if(node[idx<<1].rsum+node[idx<<1|1].lsum>=val)
     85             return node[idx<<1].right-node[idx<<1].rsum+1;
     86         else
     87            return update2(val,idx<<1|1);
     88     }
     89     else {
     90         return 0;
     91     }
     92 }
     93 int main(){
     94     scanf("%d%d",&n,&m);
     95     build(1,n,1);
     96     for(int i=1;i<=m;i++){
     97         cin>>u;
     98         if(u==1){
     99             cin>>v;
    100             int ans=update2(v,1);
    101             printf("%d
    ",ans);
    102             if(ans>0)//这里不要有分好,我几次就是死在了这里 
    103             update1(ans,ans+v-1,1,1);
    104         }
    105         else{
    106             cin>>v>>w;
    107             update1(v,v+w-1,0,1);
    108         }
    109     }
    110 }
    View Code
  • 相关阅读:
    UI 常用方法总结之--- UITableView
    UITextFiled 通知监听
    ios 本地通知
    AFNetworking 请求头的设置
    UI总结
    gitlab-server环境搭建
    redis 配置文件示例
    搭建spark集群
    kafka集群安装
    zookeeper集群搭建
  • 原文地址:https://www.cnblogs.com/chujian123/p/3431320.html
Copyright © 2011-2022 走看看