POJ - 3667 - Hotel - 芒果糕


http://poj.org/problem?id=3667
The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel has N (1 ≤ N ≤ 50,000) rooms all located on the same side of an extremely long hallway (all the better to see the lake, of course).
The cows and other visitors arrive in groups of size Di (1 ≤ Di ≤ N) and approach the front desk to check in. Each group i requests a set of Di contiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbers r..r+Di-1 if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value of r to be the smallest possible.
Visitors also depart the hotel from groups of contiguous rooms. Checkout i has the parameters Xi and Di which specify the vacating of rooms Xi ..Xi +Di-1 (1 ≤ Xi ≤ N-Di+1). Some (or all) of those rooms might be empty before the checkout.
Your job is to assist Canmuu by processing M (1 ≤ M < 50,000) checkin/checkout requests. The hotel is initially unoccupied.
Input
* Line 1: Two space-separated integers: N and M
* Lines 2..M+1: Line i+1 contains request expressed as one of two possible formats: (a) Two space separated integers representing a check-in request: 1 and D(b) Three space-separated integers representing a check-out: 2, Xi, and Di
Output
* Lines 1.....: For each check-in request, output a single line with a single integer r, the first room in the contiguous sequence of rooms to be occupied. If the request cannot be satisfied, output 0.
Sample Input
10 6
1 3
1 3
1 3
1 3
2 5 5
1 6
Sample Output
1
4
7
0
5
POJ - 3667 - Hotel - 芒果糕
有N个连续编号的房间的酒店,M次操作。包括x个人入住连续的房间,x开始的y个人登出。求每次入住房间的开始房号,不能入住则输出0.
比较复杂的线段树+懒惰标记。根据题意,其实是求连续的01串中,最左侧的连续k个1的序列的位置。
需要维护3个参数,每个区间最长连续1序列的长度sum,左侧开始往右最长的1序列lsum,右侧开始往左最长的1序列rsum。
这样在PushUp时,首先继承左儿子的lsum和右儿子的rsum,然后判断左儿子的lsum是否覆盖左儿子整个区间,如果是则说明左儿子和右儿子是左相连的,lsum更新为左右儿子的lsum之和。其次判断右儿子的rsum是否覆盖右儿子整个区间,如果是则同理,rsum更新为左右儿子的rsum只和。最后,sum取左右儿子sum以及左儿子rsum和右儿子lsum之和的最大值。左儿子rsum和右儿子lsum之和即为左右区间合并点所在的最长1序列。
PushDown时,首先继承父亲的标记。如果标记为1入住,则儿子的所有序列长度更新为0,否则更新为对应区间长度。最后标记还原为-1.这里为了和登出的0区分开,用-1表示没有标记。
建立线段树时,序列长度默认为区间长度。
更新时,搜索到子集时,更新标记,并且序列长度根据标记更新为0或者区间长度。然后PushDown,PushUp。
查询时,优先查询左子树,其次查询左右区间连接部分,最后查询右子树。
最后,每次入住操作的查询后,如果可以入住,则需要更新对应区间为1状态。
http://www.acmerblog.com/POJ-3667-Hotel-blog-1124.html
009class point
010{
011    int l,r,max,cov;
012}
013 public class Main{
014  // static int  MAX = 50010;
015 
016 
017   point p[];
018   public Main(){
019      p=new point[131070];
020      for(int i=0;i< p.length;i++)
021         p[i]=new point();
022   }
023   
024  void push_up(int l,int r,int rt)
025  {
026    p[rt].l = p[rt<<1].l;
027    p[rt].r = p[rt<<1|1].r;
028    int mid = r+l>>1;
029    if(p[rt].l==mid-l+1) p[rt].l+=p[rt<<1|1].l;
030    if(p[rt].r==r-mid) p[rt].r+=p[rt<<1].r;
031    p[rt].max =Math.max(Math.max(p[rt<<1].max,p[rt<<1|1].max),p[rt<<1].r+p[rt<<1|1].l);
032 }
033 
034  void push_down(int l,int r,int rt)
035  {
036    if(p[rt].cov!=-1)
037    {
038        p[rt<<1].cov = p[rt<<1|1].cov = p[rt].cov;
039        if(p[rt].cov==1)
040        p[rt<<1].l = p[rt<<1|1].l = p[rt<<1].r = p[rt<<1|1].r = p[rt<<1].max = p[rt<<1|1].max = 0;
041        else
042        {
043            int mid = r+l>>1;
044            p[rt<<1].l = p[rt<<1].r = p[rt<<1].max = mid-l+1;
045            p[rt<<1|1].l = p[rt<<1|1].r = p[rt<<1|1].max = r-mid;
046        }
047        p[rt].cov = -1;
048    }
049 }
050 
051 void build(int l,int r,int rt){
052    p[rt].l = p[rt].r = p[rt].max = r-l+1;
053    p[rt].cov = -1;
054    if(l==r)
055    {
056        return;
057    }
058    int mid = r+l>>1;
059    build(l,mid,rt<<1);
060    build(mid+1,r,rt<<1|1);
061 }
062 
063 //a==1,填满[L,R],a=0清空区间[L,R]
064 void update(int a,int L,int R,int l,int r,int rt)
065 {
066    if(L<=l&&R>=r)
067    {
068        if(a==1)
069          p[rt].l = p[rt].r = p[rt].max = 0;
070        else
071          p[rt].l = p[rt].r = p[rt].max = r-l+1;
072        p[rt].cov = a;
073        return;
074    }
075    int mid = r+l>>1;
076    push_down(l,r,rt);
077    if(L<=mid) update(a,L,R,l,mid,rt<<1);
078    if(R>mid) update(a,L,R,mid+1,r,rt<<1|1);
079    push_up(l,r,rt);
080 }
081  
082  int query(int a,int l,int r,int rt)
083  {
084    if(l==r)
085    {
086        return l;
087    }
088    int mid = r+l>>1;
089    push_down(l,r,rt);
090    if(p[rt<<1].max>=a) return query(a,l,mid,rt<<1);
091    if(p[rt<<1].r+p[rt<<1|1].l>=a) return mid-p[rt<<1].r+1;
092    return query(a,mid+1,r,rt<<1|1);
093 }
094 
095  public int getMax(){
096    return p[1].max;
097  }
098  public static void  main(String args[]) throws IOException{
099 
100    StreamTokenizer st = new StreamTokenizer(new BufferedReader(  
101      new InputStreamReader(System.in)));  
102      PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));  
103      
104 
105    int n,m,k,x,y;
106    while(st.nextToken() != StreamTokenizer.TT_EOF)
107    {
108         
109         n= (int) st.nval;
110          st.nextToken();  
111         m= (int) st.nval;
112         Main ma=new Main();
113         
114        ma.build(1,n,1);
115        while(m-->0)
116        {
117            st.nextToken();  
118            k=(int) st.nval;
119            if(k==1)
120            {
121                 st.nextToken();  
122                x= (int) st.nval;
123                if(ma.getMax()< x) System.out.println("0");
124                else
125                {
126                    int tmp =ma.query(x,1,n,1);
127                    System.out.printf("%d\n",tmp);
128                    ma.update(1,tmp,tmp+x-1,1,n,1);
129                }
130            }
131            else
132            {
133                 st.nextToken();  
134                x=(int) st.nval;
135                 st.nextToken();
136                y=(int) st.nval;
137                ma.update(0,x,x+y-1,1,n,1);
138            }
139        }
140       out.flush();  
141    }
142   }
143}
http://www.java3z.com/cwbwebhome/article/article17/acm922.html
线段树,区间合并,区间替换,查询最左断点
Read full article from POJ - 3667 - Hotel - 芒果糕

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts