BZOJ 2850

这题,由于是在学习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 }
原文地址:https://www.cnblogs.com/lvyouyw/p/6857587.html