P4475 巧克力王国 k-d tree

时间:2023-03-08 22:09:51

思路:\(k-d\ tree\)

提交:2次

错因:\(query\)时有一个\(mx\)误写成\(mn\)窝太菜了。

题解:

先把\(k-d\ tree\)建出来,然后查询时判一下整个矩形是否整体\(or\)一部分\(or\)全都不 满足\(Ax+By<C\),来决定直接返回子树和,还是递归子树,还是返回\(0\)

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ull unsigned long long
#define ll long long
#define R register ll
using namespace std;
#define pause (for(R i=1;i<=10000000000;++i))
#define In freopen("NOIPAK++.in","r",stdin)
#define Out freopen("out.out","w",stdout)
namespace Fread {
static char B[1<<15],*S=B,*D=B;
#ifndef JACK
#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
#endif
inline int g() {
R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
} inline bool isempty(const char& ch) {return (ch<=36||ch>=127);}
inline void gs(char* s) {
register char ch; while(isempty(ch=getchar()));
do *s++=ch; while(!isempty(ch=getchar()));
}
} using Fread::g; using Fread::gs;
namespace Luitaryi {
const int N=50010;
int n,m,rt,D,tot;
ll A,B,C;
struct P{int d[2],w;
inline bool operator <(const P& that) const {return d[D]<that.d[D];}
}p[N];
struct node {
int lson,rson,sz,mx[2],mn[2]; ll sum; P p;
#define ls (t[tr].lson)
#define rs (t[tr].rson)
#define sum(tr) (t[tr].sum)
#define mx(tr,i) (t[tr].mx[i])
#define mn(tr,i) (t[tr].mn[i])
#define P(tr,i) (t[tr].p.d[i])
#define vl(tr) (t[tr].p.w)
}t[N];
inline void upd(int tr) {
for(R i=0;i<=1;++i) {
mx(tr,i)=mn(tr,i)=P(tr,i);
if(ls) mx(tr,i)=max(mx(tr,i),mx(ls,i)),mn(tr,i)=min(mn(tr,i),mn(ls,i));
if(rs) mx(tr,i)=max(mx(tr,i),mx(rs,i)),mn(tr,i)=min(mn(tr,i),mn(rs,i));
} sum(tr)=sum(ls)+sum(rs)+vl(tr);
}
inline int build(int l,int r,int dim) {
if(l>r) return 0; R tr=++tot,md=l+r>>1;
D=dim,nth_element(p+l,p+md,p+r+1);
t[tr].p=p[md];
ls=build(l,md-1,dim^1),rs=build(md+1,r,dim^1);
upd(tr); return tr;
}
inline bool ck(int x,int y) {return A*x+B*y<C;}
inline ll query(int tr) { R cnt=0;
cnt+=ck(mn(tr,0),mn(tr,1)),cnt+=ck(mn(tr,0),mx(tr,1));
cnt+=ck(mx(tr,0),mn(tr,1)),cnt+=ck(mx(tr,0),mx(tr,1));
if(cnt==4) return sum(tr);
if(!cnt) return 0;
R ret=0; if(ck(P(tr,0),P(tr,1))) ret+=vl(tr);
if(ls) ret+=query(ls); if(rs) ret+=query(rs);
return ret;
}
inline void main() {
n=g(),m=g(); for(R i=1;i<=n;++i) p[i].d[0]=g(),p[i].d[1]=g(),p[i].w=g();
rt=build(1,n,0); for(R i=1;i<=m;++i) {
A=g(),B=g(),C=g(); printf("%lld\n",query(rt));
}
}
}
signed main() {
Luitaryi::main(); return 0;
}

2019.07.22