V-Ice-cream Tycoon (line segment tree)
There are two types of operations: ARRIVE a B indicates that the purchase quantity of ice cream whose unit price is B is a, BUY a B indicates that students get B yuan in total, and want to BUY an ice cream which is as cheap as possible, if you can purchase, output HAPPY, otherwise output UNHAPPY"
The operation is quite simple, with single-point update and then push_up. But it seems quite troublesome to write.
First, read all the operations, discretize the purchased ice cream unit price, establish a line segment tree, and then update the corresponding ice cream quantity and price for ARRIVE operations in the read order, for "BUY operations, search for the left subtree first, that is, try to make it cheaper. If you can BUY it, update the number and price of the corresponding interval.
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include # define LL long # define eps 1e-12 # define PI acos (-1.0) # define PP pair
Using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 100010; const int mod = 1000000007; struct Info {char str [10]; LL num; LL mon ;} info [maxn]; struct node {int l, r; LL num; // Number of ice cream LL sum; // total price LL price; // ice cream unit price} tree [maxn * 4]; LL x [maxn]; int Binsearch (int l, int r, LL key) {int mid, low = l, high = r; while (high> = low) {mid = (low + high)> 1; if (x [mid] = key) return mid; if (x [mid]> k Ey) high = mid-1; else low = mid + 1;} return-1;} void build (int v, int l, int r) {tree [v]. l = l; tree [v]. r = r; tree [v]. num = tree [v]. sum = tree [v]. price = 0; if (l = r) return; int mid = (l + r)> 1; build (v * 2, l, mid ); build (v * 2 + 1, mid + 1, r);} void push_down (int v) {if (tree [v]. l = tree [v]. r) return; if (tree [v]. num = 0 & tree [v]. sum = 0) {tree [v * 2]. num = tree [v * 2 + 1]. num = 0; tree [v * 2]. sum = tree [v * 2 + 1 ]. Sum = 0 ;}} void push_up (int v) {tree [v]. num = tree [v * 2]. num + tree [v * 2 + 1]. num; tree [v]. sum = tree [v * 2]. sum + tree [v * 2 + 1]. sum;} void update (int v, int pos, LL num, LL mon, LL t) {if (tree [v]. l = tree [v]. r) {if (tree [v]. price = 0) tree [v]. price = mon; tree [v]. num + = num; tree [v]. sum + = t; return;} push_down (v); // key. Do not omit it. Int mid = (tree [v]. l + tree [v]. r)> 1; if (pos <= mid) update (v * 2, pos, num, mon, t); else update (v * 2 + 1, pos, num, mon, t); push_up (v);} void update_1 (int v, LL num, LL sum) {tree [v]. num-= num; tree [v]. sum-= sum; if (tree [v]. l = tree [v]. r) return; if (tree [v * 2]. num> = num) update_1 (v * 2, num, sum); else {LL tmp1 = num-tree [v * 2]. num; LL tmp2 = sum-tree [v * 2]. sum; tree [v * 2]. num = 0; tree [v * 2]. sum = 0; update_1 (v * 2 + 1, tmp1, Tmp2);} LL query (int v, LL num) {if (tree [v]. num <num) return-1; if (tree [v]. num = num) {return tree [v]. sum;} if (tree [v]. l = tree [v]. r) {return tree [v]. price * num;} if (tree [v * 2]. num> = num) return query (v * 2, num); else {LL res = query (v * 2 + 1, num-tree [v * 2]. num); return tree [v * 2]. sum + res ;}} int main () {int t1, t2, k; LL a, B; char ch [10]; t1 = 0; t2 = 0; while (~ Scanf (% s % I64d % I64d, ch, & a, & B) {struct Info tmp; strcpy (tmp. str, ch); tmp. num = a; tmp. mon = B; info [++ t1] = tmp; if (ch [0] = 'A') x [++ t2] = B ;} sort (x + 1, x + 1 + t2); k = 1; for (int I = 2; I <= t2; I ++) {if (x [I]! = X [I-1]) x [+ + k] = x [I];} build (, k); for (int I = 1; I <= t1; I ++) {if (info [I]. str [0] = 'A') {int pos = Binsearch (1, k, info [I]. mon); LL t = info [I]. num * info [I]. mon; update (1, pos, info [I]. num, info [I]. mon, t); // number, price, and unit price of ice cream updated on a single point} else {LL res = query (1, info [I]. num); if (res =-1) // The total number is smaller than the purchased number printf (UNHAPPY); else {if (info [I]. mon> = res) {printf (HAPPY); update_1 (1, info [I]. num, res); // if you can purchase the product, update the number and price of the corresponding interval} else printf (UNHAPPY) ;}} return 0 ;}