这题,由于是在学习KD_tree的时候从黄学长那里找到的题,所以知道了它是一道KD_tree的题,不然我一定会认为它是一个半平面交维护什么鬼的。
我个人理解KD_tree就是一种玄学暴力,利用对数据的一些处理组织成了树的形式,利用估价函数进行剪枝,然后就可以比较方便的查询。
对于这道题,要求满足Ax+By<C的点对的个数,那么我们建出KD_tree,然后我们的估价函数就是如果这个子树内的所有点都满足或不满足,我们就直接返回答案,否则就递归到左右子树,感觉KD_tree的复杂度还是很玄学的...
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define maxn 50005 6 typedef long long LL; 7 struct KD_tree 8 { 9 int ls,rs,mx[2],mn[2],d[2],key; 10 LL sum; 11 }t[maxn]; 12 int n,m,cmp_d,rt; 13 LL A,B,C; 14 15 inline int read(void) 16 { 17 int x=0,f=1; 18 char ch=getchar(); 19 while (ch>'9'||ch<'0') 20 { 21 if (ch=='-') f=-1; 22 ch=getchar(); 23 } 24 while (ch>='0'&&ch<='9') 25 { 26 x=x*10+ch-'0'; 27 ch=getchar(); 28 } 29 return x*f; 30 } 31 32 void KD_update(int x) 33 { 34 int ls=t[x].ls; 35 int rs=t[x].rs; 36 if (ls) 37 { 38 t[x].mx[0]=max(t[x].mx[0],t[ls].mx[0]); 39 t[x].mx[1]=max(t[x].mx[1],t[ls].mx[1]); 40 t[x].mn[0]=min(t[x].mn[0],t[ls].mn[0]); 41 t[x].mn[1]=min(t[x].mn[1],t[ls].mn[1]); 42 } 43 if (rs) 44 { 45 t[x].mx[0]=max(t[x].mx[0],t[rs].mx[0]); 46 t[x].mx[1]=max(t[x].mx[1],t[rs].mx[1]); 47 t[x].mn[0]=min(t[x].mn[0],t[rs].mn[0]); 48 t[x].mn[1]=min(t[x].mn[1],t[rs].mn[1]); 49 } 50 t[x].sum=t[ls].sum+t[rs].sum+t[x].key; 51 } 52 53 inline bool cmp(KD_tree a,KD_tree b) 54 { 55 int x=a.d[cmp_d],y=b.d[cmp_d]; 56 return x<y||(x==y&&a.d[!cmp_d]<b.d[!cmp_d]); 57 } 58 59 int KD_build(int l,int r,int D) 60 { 61 int mid=(l+r)>>1; 62 cmp_d=D; 63 nth_element(t+l,t+mid,t+r+1,cmp); 64 t[mid].mx[0]=t[mid].mn[0]=t[mid].d[0]; 65 t[mid].mx[1]=t[mid].mn[1]=t[mid].d[1]; 66 if (l<mid) t[mid].ls=KD_build(l,mid-1,D^1); 67 if (r>mid) t[mid].rs=KD_build(mid+1,r,D^1); 68 KD_update(mid); 69 return mid; 70 } 71 72 int check(int x) 73 { 74 int cnt=0; 75 cnt+= A*t[x].mn[0]+B*t[x].mn[1]<C; 76 cnt+= A*t[x].mn[0]+B*t[x].mx[1]<C; 77 cnt+= A*t[x].mx[0]+B*t[x].mn[1]<C; 78 cnt+= A*t[x].mx[0]+B*t[x].mx[1]<C; 79 return cnt; 80 } 81 82 LL KD_query(int x) 83 { 84 int cnt=check(x); 85 if (cnt==4) return t[x].sum; 86 if (cnt==0) return 0; 87 LL tmp=0; 88 if (A*t[x].d[0]+B*t[x].d[1]<C) tmp=t[x].key; 89 if (t[x].ls) tmp+=KD_query(t[x].ls); 90 if (t[x].rs) tmp+=KD_query(t[x].rs); 91 return tmp; 92 } 93 94 int main() 95 { 96 n=read();m=read(); 97 for (int i=1;i<=n;i++) 98 t[i].d[0]=read(),t[i].d[1]=read(),t[i].key=read(); 99 rt=KD_build(1,n,0); 100 for (int i=1;i<=m;i++) 101 { 102 A=read();B=read();C=read(); 103 printf("%lld\n",KD_query(rt)); 104 } 105 return 0; 106 }