裸kd-tree,注意估价函数的写法,每个点记个sum。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
#define ll long long
#define maxn 60000
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll A,B,C,ans;
int D,n,m,rt;
struct node
{
int d[2],mx[2],mn[2],v,l,r;
ll sum;
friend bool operator < (node aa,node bb)
{
return aa.d[D]<bb.d[D];
}
}p[maxn];
bool check(int x,int y)
{
return x*A+y*B<C;
}
struct tree
{
node t[maxn];
int cal(int x)
{
int tmp=0;
tmp+=check(t[x].mn[0],t[x].mn[1]);
tmp+=check(t[x].mn[0],t[x].mx[1]);
tmp+=check(t[x].mx[0],t[x].mn[1]);
tmp+=check(t[x].mx[0],t[x].mx[1]);
return tmp;
}
void update(int x)
{
for(int i=0;i<2;i++)
{
if(t[x].l)
{
t[x].mn[i]=min(t[x].mn[i],t[t[x].l].mn[i]);
t[x].mx[i]=max(t[x].mx[i],t[t[x].l].mx[i]);
}
if(t[x].r)
{
t[x].mn[i]=min(t[x].mn[i],t[t[x].r].mn[i]);
t[x].mx[i]=max(t[x].mx[i],t[t[x].r].mx[i]);
}
}
t[x].sum=t[x].v+t[t[x].l].sum+t[t[x].r].sum;
}
int build(int l,int r,int now)
{
D=now;
int mid=(l+r)>>1;
nth_element(p+l,p+mid+1,p+r+1);
t[mid]=p[mid];
for(int i=0;i<2;i++)
t[mid].mn[i]=t[mid].mx[i]=t[mid].d[i];
if(l<mid) t[mid].l=build(l,mid-1,now^1);
if(mid<r) t[mid].r=build(mid+1,r,now^1);
update(mid);
return mid;
}
void query(int x)
{
int l=t[x].l,r=t[x].r;
if(check(t[x].d[0],t[x].d[1])) ans+=t[x].v;
int tl=0,tr=0;
if(l) tl=cal(l);
if(r) tr=cal(r);
if(tl==4) ans+=t[l].sum;
else if(tl) query(l);
if(tr==4) ans+=t[r].sum;
else if(tr) query(r);
}
}kd;
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
p[i].d[0]=read(),p[i].d[1]=read(),p[i].v=read();
rt=kd.build(1,n,0);
while(m--)
{
A=read(),B=read(),C=read();
ans=0;
kd.query(rt);
printf("%lld\n",ans);
}
return 0;
}