1. 程式人生 > >POJ - 3667 Hotel(線段樹區間合並)

POJ - 3667 Hotel(線段樹區間合並)

而且 algorithm ons back -- 停車場 sig 標記 efi

題目鏈接

題意:

給定一個有$N$個車位的停車場(都在一條直線上),現在有有兩種操作

$1.x $ 要停連續的停$x$輛車,輸出第一輛車停的位置(盡量靠前),不能就輸出$0$;

$2.x,d$ 從x位置開始開走連續的$d$輛車。

思路:

一個線段樹區間和問題,而且滿足區間可加性,就要用到區間合並。

  1 /*
  2 *  Author: windystreet
  3 *  Date  : 2018-08-15 10:29:55
  4 *  Motto : Think twice, code once.
  5 */
  6 #include <stdio.h>
  7
#include <string.h> 8 #include <algorithm> 9 10 using namespace std; 11 12 #define X first 13 #define Y second 14 #define eps 1e-5 15 #define gcd __gcd 16 #define pb push_back 17 #define PI acos(-1.0) 18 #define lowbit(x) (x)&(-x) 19 #define bug printf("!!!!!\n"); 20
#define mem(x,y) memset(x,y,sizeof(x)) 21 22 typedef long long LL; 23 typedef long double LD; 24 typedef pair<int,int> pii; 25 typedef unsigned long long uLL; 26 27 const int maxn = 5e4+7; 28 const int INF = 1<<30; 29 const int mod = 1e9+7; 30 31 struct Tree 32
{ 33 int l,r,lazy; 34 int ls,rs,ms; // 區間前綴,後綴,最大值 35 }tree[maxn<<2]; 36 void build(int rt,int l,int r){ 37 tree[rt].r = r;tree[rt].l = l;tree[rt].lazy = -1; 38 if(l == r){ 39 tree[rt].ms = tree[rt].ls = tree[rt].rs = 1;return; 40 } 41 int mid = ( l + r ) >> 1; 42 build(rt<<1,l,mid); 43 build(rt<<1|1,mid+1,r); 44 tree[rt].ms = tree[rt].ls = tree[rt].rs = tree[rt<<1].ms + tree[rt<<1|1].ms; 45 } 46 void pushdown(int rt){ 47 if(tree[rt].lazy!=-1){ // 下推標記 48 int mid = (tree[rt].r + tree[rt].l )>>1; 49 tree[rt<<1|1].lazy = tree[rt<<1].lazy = tree[rt].lazy; 50 tree[rt<<1].ls = tree[rt<<1].rs = tree[rt<<1].ms = (mid - tree[rt].l+1)*tree[rt].lazy; 51 tree[rt<<1|1].ls = tree[rt<<1|1].rs = tree[rt<<1|1].ms = (tree[rt].r -mid)*tree[rt].lazy; 52 tree[rt].lazy = -1; 53 } 54 } 55 void pushup(int rt){ // 向上更新 56 tree[rt].ls = tree[rt<<1].ls; 57 tree[rt].rs = tree[rt<<1|1].rs; 58 if(tree[rt<<1].ls == (tree[rt<<1].r - tree[rt<<1].l + 1)){ // 區間合並 59 tree[rt].ls += tree[rt<<1|1].ls; 60 } 61 if(tree[rt<<1|1].rs == (tree[rt<<1|1].r - tree[rt<<1|1].l + 1)){ 62 tree[rt].rs += tree[rt<<1].rs; 63 } 64 tree[rt].ms = max(max(tree[rt<<1|1].ms,tree[rt<<1].ms),tree[rt<<1].rs+tree[rt<<1|1].ls); 65 } 66 void update(int rt,int L,int R,int l,int r,int v){ 67 if(l<=L&&R<=r){ 68 tree[rt].ls = tree[rt].rs = tree[rt].ms = v*(R - L + 1); 69 tree[rt].lazy = v;return; 70 } 71 pushdown(rt); 72 int mid = ( L + R) >>1; 73 if(l<=mid) update(rt<<1,L,mid,l,r,v); 74 if(r>mid) update(rt<<1|1,mid+1,R,l,r,v); 75 pushup(rt); 76 } 77 int query(int rt,int L,int R,int v){ 78 pushdown(rt); 79 int mid = (L + R) >>1; 80 if(tree[rt<<1].ms>=v){ // 盡量靠前 81 return query(rt<<1,L,mid,v); 82 }else if(tree[rt<<1].rs + tree[rt<<1|1].ls>=v){ 83 return mid - tree[rt<<1].rs + 1; 84 }else{ 85 return query(rt<<1|1,mid+1,R,v); 86 } 87 } 88 89 void solve(){ 90 int n,m,op,x,y; 91 while(scanf("%d%d",&n,&m)!=EOF){ 92 build(1,1,n); 93 while(m--){ 94 scanf("%d",&op); 95 if(op==1){ 96 scanf("%d",&x); 97 if(tree[1].ms<x){ 98 puts("0"); 99 }else{ 100 int pos = query(1,1,n,x); 101 printf("%d\n",pos); 102 update(1,1,n,pos,pos+x-1,0); 103 } 104 105 }else{ 106 scanf("%d%d",&x,&y); 107 update(1,1,n,x,x+y-1,1); 108 } 109 } 110 } 111 112 return; 113 } 114 115 int main() 116 { 117 // freopen("F:\\in.txt","r",stdin); 118 // freopen("out.txt","w",stdout); 119 // ios::sync_with_stdio(false); 120 int t = 1; 121 //scanf("%d",&t); 122 while(t--){ 123 // printf("Case %d: ",cas++); 124 solve(); 125 } 126 return 0; 127 }

POJ - 3667 Hotel(線段樹區間合並)