巧克力王国 BZOJ 2850
巧克力王國
【問題描述】
巧克力王國里的巧克力都是由牛奶和可可做成的。但是并不是每一塊巧克力都受王國人民的歡迎,因為大家都不喜歡過于甜的巧克力。對于每一塊巧克力,我們設x和y為其牛奶和可可的含量。由于每個人對于甜的程度都有自己的評判標準,所以每個人都有兩個參數a和b,分別為他自己為牛奶和可可定義的權重,因此牛奶和可可含量分別為x和y的巧克力對于他的甜味程度即為ax + by。而每個人又有一個甜味限度c,所有甜味程度大于等于c的巧克力他都無法接受。每塊巧克力都有一個美味值h。現在我們想知道對于每個人,他所能接受的巧克力的美味值之和為多少
【輸入格式】第一行兩個正整數n和m,分別表示巧克力個數和詢問個數。接下來n行,每行三個整數x,y,h,含義如題目所示。再接下來m行,每行三個整數a,b,c,含義如題目所示。
【輸出格式】輸出m行,其中第i行表示第i個人所能接受的巧克力的美味值之和。
【樣例輸入】3 3
1 2 5
3 1 4
2 2 1
2 1 6
1 3 5
1 3 7
【樣例輸出】
5
0
4
【數據范圍】
1 <= n, m <= 50000,-10^9 <= a, b, x, y <= 10^9。
題解:
考慮 ax + by - c 其實是平面上的一條直線,x、y就是點的橫坐標和縱坐標
要求 ax + by < c ,就是要求點在 ax + by - c 的下方
那么就用KD樹就好了
程序中用了一個 nth_element(a + l, a + m, a + r + 1, cmp) 函數
就是按cmp定義的大小規則,將a數組中l到r中第m大的數放在第m位,比這個數小的數在第m位前,其他在第m位后(亂序)
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cstdio> 6 #include<cmath> 7 #define lc(i) tr[i].l 8 #define rc(i) tr[i].r 9 #define mi_x(i) tr[i].mi_x 10 #define ma_x(i) tr[i].ma_x 11 #define mi_y(i) tr[i].mi_y 12 #define ma_y(i) tr[i].ma_y 13 #define sum(i) tr[i].sum 14 typedef long long lol; 15 using namespace std; 16 inline lol Get() 17 { 18 lol x; 19 lol o = 1; 20 char c; 21 while((c = getchar()) < '0' || c > '9') 22 if(c == '-') 23 o = -1; 24 x = c - '0'; 25 while((c = getchar()) >= '0' && c <= '9') x = x * 10 + c - '0'; 26 return x * o; 27 } 28 const int me = 1000233; 29 const lol inf = 214748364721474836; 30 struct dot 31 { 32 int l, r; 33 lol x, y, z, sum, mi_x, mi_y, ma_x, ma_y; 34 dot() 35 { 36 mi_x = mi_y = inf; 37 ma_x = ma_y = -inf; 38 } 39 }; 40 dot a[me], tr[me]; 41 lol x, y, z; 42 int n, m; 43 int flag; 44 lol ans; 45 inline bool operator < (const dot &a, const dot &b) 46 { 47 if(!flag) return a.x < b.x; 48 return a.y < b.y; 49 } 50 inline void Update(const int &x) 51 { 52 int l = lc(x), r = rc(x); 53 mi_x(x) = min(tr[x].x, min(mi_x(l), mi_x(r))); 54 ma_x(x) = max(tr[x].x, max(ma_x(l), ma_x(r))); 55 mi_y(x) = min(tr[x].y, min(mi_y(l), mi_y(r))); 56 ma_y(x) = max(tr[x].y, max(ma_y(l), ma_y(r))); 57 sum(x) = sum(l) + sum(r) + tr[x].z; 58 } 59 int Build(const int &l, const int &r, const int &e) 60 { 61 int mi = l + r >> 1; 62 flag = e; 63 nth_element(a + l, a + mi, a + r + 1); 64 tr[mi] = a[mi]; 65 if(l < mi) lc(mi) = Build(l, mi - 1, e ^ 1); 66 if(r > mi) rc(mi) = Build(mi + 1, r, e ^ 1); 67 Update(mi); 68 return mi; 69 } 70 inline int Check(const int &wx, const int &wy) 71 { 72 return (lol) wx * x + wy * y < z; 73 } 74 inline int Pos(const int &w) 75 { 76 if(!w) return 0; 77 return Check(mi_x(w), mi_y(w)) + Check(mi_x(w), ma_y(w)) + Check(ma_x(w), mi_y(w)) + Check(ma_x(w), ma_y(w)); 78 } 79 void Ask(const int &w) 80 { 81 int l = lc(w), r = rc(w); 82 if(Check(tr[w].x, tr[w].y)) ans += tr[w].z; 83 int le = Pos(l); 84 if(le) 85 if(le == 4) ans += sum(l); 86 else Ask(l); 87 int ri = Pos(rc(w)); 88 if(ri) 89 if(ri == 4) ans += sum(r); 90 else Ask(r); 91 } 92 int main() 93 { 94 n = Get(), m = Get(); 95 for(int i = 1; i <= n; ++i) 96 a[i].x = Get(), a[i].y = Get(), a[i].z = Get(); 97 Build(1, n, 0); 98 for(int i = 1; i <= m; ++i) 99 { 100 x = Get(), y = Get(), z = Get(); 101 ans = 0; 102 Ask(1 + n >> 1); 103 printf("%lld\n", ans); 104 } 105 }轉載于:https://www.cnblogs.com/lytccc/p/6429665.html
總結
以上是生活随笔為你收集整理的巧克力王国 BZOJ 2850的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开发代码code中变量替换
- 下一篇: Linux-通配符