zoukankan      html  css  js  c++  java
  • POJ3667 Hotel 线段树区间合并

      题目链接:http://poj.org/problem?id=3667

      题意: 有一个旅馆,有N个房间排成一排,现在有两种操作,第一是有X个顾客要入住连续的X个房间,要求输出最小的左端点的位置,不能满足就输出0,第二是将以l开始,长度为X的连续房间清空。

      线段树区间合并的经典题目。每个域维护三个值,左端开始的最长连续长度,整个区间的最长连续长度,右端开始的最长连续长度。

      1 //STATUS:C++_AC_641MS_2240KB
      2 #include <functional>
      3 #include <algorithm>
      4 #include <iostream>
      5 //#include <ext/rope>
      6 #include <fstream>
      7 #include <sstream>
      8 #include <iomanip>
      9 #include <numeric>
     10 #include <cstring>
     11 #include <cassert>
     12 #include <cstdio>
     13 #include <string>
     14 #include <vector>
     15 #include <bitset>
     16 #include <queue>
     17 #include <stack>
     18 #include <cmath>
     19 #include <ctime>
     20 #include <list>
     21 #include <set>
     22 #include <map>
     23 using namespace std;
     24 //using namespace __gnu_cxx;
     25 //define
     26 #define pii pair<int,int>
     27 #define mem(a,b) memset(a,b,sizeof(a))
     28 #define lson l,mid,rt<<1
     29 #define rson mid+1,r,rt<<1|1
     30 #define PI acos(-1.0)
     31 //typedef
     32 typedef __int64 LL;
     33 typedef unsigned __int64 ULL;
     34 //const
     35 const int N=50010;
     36 const int INF=0x3f3f3f3f;
     37 const int MOD=100000,STA=8000010;
     38 const LL LNF=1LL<<60;
     39 const double EPS=1e-8;
     40 const double OO=1e15;
     41 const int dx[4]={-1,0,1,0};
     42 const int dy[4]={0,1,0,-1};
     43 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
     44 //Daily Use ...
     45 inline int sign(double x){return (x>EPS)-(x<-EPS);}
     46 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
     47 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
     48 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
     49 template<class T> inline T Min(T a,T b){return a<b?a:b;}
     50 template<class T> inline T Max(T a,T b){return a>b?a:b;}
     51 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
     52 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
     53 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
     54 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
     55 //End
     56 
     57 int lsum[N<<2],msum[N<<2],rsum[N<<2],c[N<<2];
     58 int n,m,a,b,val;
     59 
     60 void pushdown(int rt,int dl,int dr)
     61 {
     62     if(c[rt]==-1)return;
     63     c[rt<<1]=c[rt<<1|1]=c[rt];
     64     lsum[rt<<1]=msum[rt<<1]=rsum[rt<<1]=c[rt]?0:dl;
     65     lsum[rt<<1|1]=msum[rt<<1|1]=rsum[rt<<1|1]=c[rt]?0:dr;
     66 }
     67 
     68 void pushup(int rt,int dl,int dr)
     69 {
     70     c[rt]=c[rt<<1]==c[rt<<1|1]?c[rt<<1]:-1;
     71     msum[rt]=Max(msum[rt<<1],msum[rt<<1|1],rsum[rt<<1]+lsum[rt<<1|1]);
     72     lsum[rt]=lsum[rt<<1]==dl?lsum[rt<<1]+lsum[rt<<1|1]:lsum[rt<<1];
     73     rsum[rt]=rsum[rt<<1|1]==dr?rsum[rt<<1|1]+rsum[rt<<1]:rsum[rt<<1|1];
     74 }
     75 
     76 void build(int l,int r,int rt)
     77 {
     78     lsum[rt]=msum[rt]=rsum[rt]=r-l+1;
     79     c[rt]=0;
     80     if(l==r)return;
     81     int mid=(l+r)>>1;
     82     build(lson);
     83     build(rson);
     84 }
     85 
     86 void update(int l,int r,int rt)
     87 {
     88     if(a<=l && r<=b){
     89         c[rt]=val;
     90         lsum[rt]=msum[rt]=rsum[rt]=val?0:r-l+1;
     91         return;
     92     }
     93     int mid=(l+r)>>1;
     94     pushdown(rt,mid-l+1,r-mid);
     95     if(a<=mid)update(lson);
     96     if(b>mid)update(rson);
     97     pushup(rt,mid-l+1,r-mid);
     98 }
     99 
    100 int query(int l,int r,int rt)
    101 {
    102     if(l==r)return l;
    103     int mid=(l+r)>>1;
    104     pushdown(rt,mid-l+1,r-mid);
    105     if(msum[rt<<1]>=a)return query(lson);
    106     else if(rsum[rt<<1]+lsum[rt<<1|1]>=a)return mid-rsum[rt<<1]+1;
    107     else return query(rson);
    108 }
    109 
    110 int main()
    111 {
    112  //   freopen("in.txt","r",stdin);
    113     int i,j,op,s;
    114     while(~scanf("%d%d",&n,&m))
    115     {
    116         build(1,n,1);
    117         while(m--){
    118             scanf("%d",&op);
    119             if(op==1){
    120                 scanf("%d",&a);
    121                 if(msum[1]<a)printf("0\n");
    122                 else {
    123                     s=query(1,n,1);
    124                     printf("%d\n",s);
    125                     b=s+a-1;a=s;
    126                     val=1;
    127                     update(1,n,1);
    128                 }
    129             }
    130             else {
    131                 scanf("%d%d",&a,&b);
    132                 b+=a-1;val=0;
    133                 update(1,n,1);
    134             }
    135         }
    136     }
    137     return 0;
    138 }
  • 相关阅读:
    对象方法Android之多媒体使用——MediaPlayer播放音频
    程序函数C语言中异常处理的两个函数
    退出窗口[置顶] 退出Activity的方法
    循环变量hdu 1799 循环多少次?
    网页剪辑有道云笔记、印象笔记(evernote)哪个更好?
    选项选择Windows XP系统安装MySQL5.5.28图解
    修改nullMyEclipse 设置文件的默认编码
    文件应用iOS开发用keychain替代UDID
    模块执行python模块介绍 struct 二进制数据结构
    数据库字符串AVP(AttributeValue Pair)
  • 原文地址:https://www.cnblogs.com/zhsl/p/3090515.html
Copyright © 2011-2022 走看看