日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【bzoj2850】巧克力王国 KD-tree

發布時間:2024/6/30 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【bzoj2850】巧克力王国 KD-tree 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

巧克力王國里的巧克力都是由牛奶和可可做成的。但是并不是每一塊巧克力都受王國人民的歡迎,因為大家都不喜歡過于甜的巧克力。對于每一塊巧克力,我們設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


題解

KD-tree

樸素的n^2暴力顯然會TLE,我們來優化這個過程。

題目要求出某條直線下方的所有點的權值和,不過看做直線并沒有什么用。

考慮,如果能夠使得某一些點都符合條件或都不符合條件,那么就可以降低查找的時間。

所以我們使用KD-tree來維護平面上的點。查詢時,判斷一下區域內的點是否都滿足條件或都不滿足條件,可以減去大量時間。

不過時間復雜度上界貌似還是O(n^2)的

估價函數需要分4種情況討論

#include <cstdio> #include <algorithm> #define N 50010 using namespace std; typedef long long ll; struct data {ll p[2] , v , maxn[2] , minn[2] , sum;int c[2]; }a[N]; int d , root; bool cmp(data a , data b) {return a.p[d] == b.p[d] ? a.p[d ^ 1] < b.p[d ^ 1] : a.p[d] < b.p[d]; } void pushup(int k , int x) {a[k].maxn[0] = max(a[k].maxn[0] , a[x].maxn[0]);a[k].maxn[1] = max(a[k].maxn[1] , a[x].maxn[1]);a[k].minn[0] = min(a[k].minn[0] , a[x].minn[0]);a[k].minn[1] = min(a[k].minn[1] , a[x].minn[1]);a[k].sum += a[x].sum; } int build(int l , int r , int now) {int mid = (l + r) >> 1;d = now , nth_element(a + l , a + mid , a + r + 1 , cmp);a[mid].maxn[0] = a[mid].minn[0] = a[mid].p[0];a[mid].maxn[1] = a[mid].minn[1] = a[mid].p[1];a[mid].sum = a[mid].v;if(l < mid) a[mid].c[0] = build(l , mid - 1 , now ^ 1) , pushup(mid , a[mid].c[0]);if(r > mid) a[mid].c[1] = build(mid + 1 , r , now ^ 1) , pushup(mid , a[mid].c[1]);return mid; } int getdis(int k , ll x , ll y , ll z) {if(x >= 0 && y >= 0){if(x * a[k].maxn[0] + y * a[k].maxn[1] < z) return 1;if(x * a[k].minn[0] + y * a[k].minn[1] >= z) return -1;}else if(x < 0 && y >= 0){if(x * a[k].minn[0] + y * a[k].maxn[1] < z) return 1;if(x * a[k].maxn[0] + y * a[k].minn[1] >= z) return -1;}else if(x >= 0 && y < 0){if(x * a[k].maxn[0] + y * a[k].minn[1] < z) return 1;if(x * a[k].minn[0] + y * a[k].maxn[1] >= z) return -1;}else{if(x * a[k].minn[0] + y * a[k].minn[1] < z) return 1;if(x * a[k].maxn[0] + y * a[k].maxn[1] >= z) return -1;}return 0; } ll query(int k , ll x , ll y , ll z) {int t = getdis(k , x , y , z);if(t == 1) return a[k].sum;if(t == -1) return 0;ll ans = 0;if(a[k].p[0] * x + a[k].p[1] * y < z) ans += a[k].v;if(a[k].c[0]) ans += query(a[k].c[0] , x , y , z);if(a[k].c[1]) ans += query(a[k].c[1] , x , y , z);return ans; } int main() {int n , m , i;ll x , y , z;scanf("%d%d" , &n , &m);for(i = 1 ; i <= n ; i ++ ) scanf("%lld%lld%lld" , &a[i].p[0] , &a[i].p[1] , &a[i].v);root = build(1 , n , 0);while(m -- ) scanf("%lld%lld%lld" , &x , &y , &z) , printf("%lld\n" , query(root , x , y , z));return 0; }

?

?

轉載于:https://www.cnblogs.com/GXZlegend/p/7110220.html

總結

以上是生活随笔為你收集整理的【bzoj2850】巧克力王国 KD-tree的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。