P4475 巧克力王国 k-d tree

思路:\(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

posted @ 2019-07-25 09:37  LuitaryiJack  阅读(191)  评论(0编辑  收藏  举报