311. Ice-cream Tycoon
Memory limit: 65536 kilobytes
output: standard
You've recently started an ice-cream business in a local school. During a day you have many suppliers delivering the ice-cream for you, and many students buying it from you. You are not allowed to set the prices, as you are told the price for each piece of ice-cream by the suppliers.
The day is described with a sequence of queries. Each query can be either
ARRIVE n c
, meaning that a supplier has delivered n pieces of ice-cream priced c each to you, or
BUY n t
, meaning that a student wants to buy n pieces of ice-cream, having a total of t money. The latter is processed as follows: in case n cheapest pieces of ice-cream you have cost no more than t (together), you sell those n cheapest pieces to the student; in case they cost more, she gets nothing. You start the day with no ice-cream.
For each student, output
HAPPY
if she gets her ice-cream, and
UNHAPPY
if she doesn't.
The input file contains between 1 and 105 queries (inclusive), each on a separate line. The queries are formatted as described above, either
ARRIVE n c
or
BUY n t
, 1 ≤ n, c ≤ 106, 1 ≤ t ≤ 1012.
For each
BUY
-query output one line, containing either the word
HAPPY
or the word
UNHAPPY
(answers should be in the same order as the corresponding queries).
sample input |
sample output |
ARRIVE 1 1 ARRIVE 10 200 BUY 5 900 BUY 5 900 BUY 5 1000 |
HAPPY UNHAPPY HAPPY |
基础线段树。
线段树维护每个点有的个数和总和。
需要给某个点加上一个个数,清空一个区间的值,查询一个区间的总价值和。
需要离线下,离散化处理、
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2014/5/2 11:48:25 4 File Name :E:2014ACM专题学习数据结构线段树SGU311.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 const int MAXN = 100010; 21 struct Node 22 { 23 int l,r; 24 long long num; 25 long long sum; 26 int c;//清空标记 27 }segTree[MAXN*3]; 28 int x[MAXN]; 29 void push_down(int i) 30 { 31 if(segTree[i].l == segTree[i].r)return; 32 if(segTree[i].c != -1) 33 { 34 segTree[i<<1].sum = segTree[(i<<1)|1].sum = 0; 35 segTree[i<<1].num = segTree[(i<<1)|1].num = 0; 36 segTree[i<<1].c = segTree[(i<<1)|1].c = 0; 37 segTree[i].c = -1; 38 } 39 } 40 void push_up(int i) 41 { 42 if(segTree[i].l == segTree[i].r)return; 43 segTree[i].sum = segTree[i<<1].sum + segTree[(i<<1)|1].sum; 44 segTree[i].num = segTree[i<<1].num + segTree[(i<<1)|1].num; 45 } 46 void build(int i,int l,int r) 47 { 48 segTree[i].l = l; 49 segTree[i].r = r; 50 segTree[i].sum = segTree[i].num = 0; 51 segTree[i].c = -1; 52 if(l == r)return; 53 int mid = (l+r)/2; 54 build(i<<1,l,mid); 55 build((i<<1)|1,mid+1,r); 56 } 57 void Add(int i,int c,int n) 58 { 59 segTree[i].sum += (long long)c*n; 60 segTree[i].num += n; 61 if(x[segTree[i].l] == c && x[segTree[i].r] == c) 62 return; 63 push_down(i); 64 if(c <= x[segTree[i<<1].r])Add(i<<1,c,n); 65 else Add((i<<1)|1,c,n); 66 } 67 //查询买前n个需要的钱 68 long long query(int i,int n) 69 { 70 if(segTree[i].l ==segTree[i].r) 71 { 72 return (long long)n*x[segTree[i].l]; 73 } 74 push_down(i); 75 if(segTree[i<<1].num >= n)return query(i<<1,n); 76 else return segTree[i<<1].sum + query((i<<1)|1,n-segTree[i<<1].num); 77 } 78 //清除前n个 79 void clear(int i,int n) 80 { 81 if(segTree[i].l == segTree[i].r) 82 { 83 segTree[i].num -= n; 84 segTree[i].sum = segTree[i].num * x[segTree[i].l]; 85 return; 86 } 87 push_down(i); 88 if(segTree[i<<1].num >= n)clear(i<<1,n); 89 else 90 { 91 clear((i<<1)|1,n-segTree[i<<1].num); 92 segTree[i<<1].num = segTree[i<<1].sum = 0; 93 segTree[i<<1].c = 0; 94 } 95 push_up(i); 96 } 97 struct Query 98 { 99 char op[10]; 100 int n; 101 long long c; 102 }q[MAXN]; 103 104 int main() 105 { 106 //freopen("in.txt","r",stdin); 107 //freopen("out.txt","w",stdout); 108 int n = 0; 109 int tot = 0; 110 while(scanf("%s%d%I64d",&q[n].op,&q[n].n,&q[n].c) == 3) 111 { 112 if(q[n].op[0] == 'A') 113 x[tot++] = q[n].c; 114 n++; 115 } 116 sort(x,x+tot); 117 tot = unique(x,x+tot) - x; 118 build(1,0,tot-1); 119 for(int i = 0;i < n;i++) 120 { 121 if(q[i].op[0] == 'A') 122 Add(1,q[i].c,q[i].n); 123 else 124 { 125 if(segTree[1].num < q[i].n)printf("UNHAPPY "); 126 else 127 { 128 if(query(1,q[i].n) > q[i].c)printf("UNHAPPY "); 129 else 130 { 131 printf("HAPPY "); 132 clear(1,q[i].n); 133 } 134 } 135 } 136 } 137 return 0; 138 }