卧薪尝胆,厚积薄发。
巧克力王国
Date: Sun Dec 16 09:37:49 CST 2018 In Category: NoCategory

Description:

平面上有 $n$ 个点,每个点有价值,多次查询某个半平面内点的权值和。
$1\leqslant n\leqslant 50000$

Solution:

$KDT$ ,如果这个节点整个都被包含就直接返回,否则递归进入有可能包含的子树。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
using namespace std;
typedef long long ll;
inline ll rd()
{
register ll res = 0,f = 1;
register char c = getchar();
while(!isdigit(c))
{
if(c == '-')f = -1;
c = getchar();
}
while(isdigit(c))
{
res = (res << 1) + (res << 3) + c - '0';
c = getchar();
}
return res * f;
}
int n,m;
#define MAXN 50010
struct node
{
int lc,rc;
ll d[2],mn[2],mx[2];
ll val,sum;
node(ll x = 0,ll y = 0,ll v = 0){val = sum = v;d[0] = x;d[1] = y;}
ll& operator [](int x){return d[x];}
}t[MAXN],p[MAXN];
int ptr = 0;
int newnode(){return ++ptr;}
int cmpd;
bool operator < (node a,node b){return a[cmpd] < b[cmpd];}
int root;
void updata(int rt)
{
for(int i = 0;i <= 1;++i)
{
if(t[rt].lc)
{
t[rt].mn[i] = min(t[rt].mn[i],t[t[rt].lc].mn[i]);
t[rt].mx[i] = max(t[rt].mx[i],t[t[rt].lc].mx[i]);
}
if(t[rt].rc)
{
t[rt].mn[i] = min(t[rt].mn[i],t[t[rt].rc].mn[i]);
t[rt].mx[i] = max(t[rt].mx[i],t[t[rt].rc].mx[i]);
}
}
t[rt].sum = t[rt].val;
if(t[rt].lc != 0)t[rt].sum += t[t[rt].lc].sum;
if(t[rt].rc != 0)t[rt].sum += t[t[rt].rc].sum;
return;
}
void build(int &rt,int l,int r,int type)
{
if(l > r)return;
rt = newnode();
cmpd = type;
int mid = ((l + r) >> 1);
nth_element(p + l,p + mid,p + r + 1);
t[rt] = p[mid];
for(int i = 0;i <= 1;++i)t[rt].mn[i] = t[rt].mx[i] = t[rt][i];
build(t[rt].lc,l,mid - 1,type ^ 1);
build(t[rt].rc,mid + 1,r,type ^ 1);
updata(rt);
return;
}
bool check(ll x,ll y,ll a,ll b,ll c)
{
return x * a + y * b < c;
}
int calc(node k,ll a,ll b,ll c)
{
int sum = 0;
sum += check(k.mn[0],k.mn[1],a,b,c);
sum += check(k.mx[0],k.mn[1],a,b,c);
sum += check(k.mn[0],k.mx[1],a,b,c);
sum += check(k.mx[0],k.mx[1],a,b,c);
return sum;
}
ll query(int rt,ll a,ll b,ll c)
{
if(calc(t[rt],a,b,c) == 4)return t[rt].sum;
ll sum = 0;
if(check(t[rt][0],t[rt][1],a,b,c)){sum += t[rt].val;}
if(t[rt].lc != 0 && calc(t[t[rt].lc],a,b,c))sum += query(t[rt].lc,a,b,c);
if(t[rt].rc != 0 && calc(t[t[rt].rc],a,b,c))sum += query(t[rt].rc,a,b,c);
return sum;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;++i)
{
p[i][0] = rd();p[i][1] = rd();p[i].val = rd();
}
build(root,1,n,0);
ll a,b,c;
for(int i = 1;i <= m;++i)
{
a = rd();b = rd();c = rd();
printf("%lld\n",query(root,a,b,c));
}
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡