码迷,mamicode.com
首页 > 其他好文 > 详细

[Luogu4475]巧克力王国

时间:2018-05-23 18:08:12      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:min   log   roo   str   class   int   cst   key   define   

luogu

题意

平面上有\(n\)个点,每个点\((x_i,y_i)\),价值为\(w_i\)\(m\)次询问,每次给出\(a_i,b_i,c_i\)求满足\(a_ix+b_iy<c_i\)的点的总价值。
\(n,m\le50000\)

sol

正解貌似是\(O(n^{1.5}\log n)\)
我只会\(kdt\)qaq
直接暴力就行了,每到一个结点判断是否可以直接返回(交集为空),全部算上(完全包含与查询范围),算是剪枝吧。

code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int gi(){
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
#define ll long long
#define ls t[o].ch[0]
#define rs t[o].ch[1]
#define cmin(a,b) (a>b?a=b:a)
#define cmax(a,b) (a<b?a=b:a)
const int N = 5e4+5;
int n,m,D,root;ll ans;
struct node{
    int d[2],key;
    bool operator < (const node &b) const
        {return d[D]<b.d[D];}
}a[N];
struct kdtree{int d[2],Min[2],Max[2],ch[2];ll sum;}t[N];
void mt(int x,int y){
    cmin(t[x].Min[0],t[y].Min[0]);cmax(t[x].Max[0],t[y].Max[0]);
    cmin(t[x].Min[1],t[y].Min[1]);cmax(t[x].Max[1],t[y].Max[1]);
    t[x].sum+=t[y].sum;
}
int build(int l,int r,int d){
    D=d;int o=l+r>>1;
    nth_element(a+l,a+o,a+r+1);
    t[o].d[0]=t[o].Min[0]=t[o].Max[0]=a[o].d[0];
    t[o].d[1]=t[o].Min[1]=t[o].Max[1]=a[o].d[1];
    t[o].sum=a[o].key;
    if (l<o) ls=build(l,o-1,d^1),mt(o,ls);
    if (o<r) rs=build(o+1,r,d^1),mt(o,rs);
    return o;
}
inline bool empty(int o,int x,int y,int z){
    if (1ll*t[o].Min[0]*x+1ll*t[o].Min[1]*y<z) return 0;
    if (1ll*t[o].Min[0]*x+1ll*t[o].Max[1]*y<z) return 0;
    if (1ll*t[o].Max[0]*x+1ll*t[o].Min[1]*y<z) return 0;
    if (1ll*t[o].Max[0]*x+1ll*t[o].Max[1]*y<z) return 0;
    return 1;
}
inline bool whole(int o,int x,int y,int z){
    if (1ll*t[o].Min[0]*x+1ll*t[o].Min[1]*y>=z) return 0;
    if (1ll*t[o].Min[0]*x+1ll*t[o].Max[1]*y>=z) return 0;
    if (1ll*t[o].Max[0]*x+1ll*t[o].Min[1]*y>=z) return 0;
    if (1ll*t[o].Max[0]*x+1ll*t[o].Max[1]*y>=z) return 0;
    return 1;
}
inline bool in(int o,int x,int y,int z){
    return 1ll*t[o].d[0]*x+1ll*t[o].d[1]*y<z;
}
void query(int o,int x,int y,int z){
    if (empty(o,x,y,z)) return;
    if (whole(o,x,y,z)) {ans+=t[o].sum;return;}
    if (in(o,x,y,z)) ans+=a[o].key;
    if (ls) query(ls,x,y,z);if (rs) query(rs,x,y,z);
}
int main(){
    n=gi();m=gi();
    for (int i=1;i<=n;++i) a[i]=(node){gi(),gi(),gi()};
    root=build(1,n,0);
    while (m--){
        int x=gi(),y=gi(),z=gi();ans=0;
        query(root,x,y,z);printf("%lld\n",ans);
    }
    return 0;
}

[Luogu4475]巧克力王国

标签:min   log   roo   str   class   int   cst   key   define   

原文地址:https://www.cnblogs.com/zhoushuyu/p/9077973.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!