【BZOJ 2850】巧克力王国
复习了下KDtree,贴一下新板子233。
1 #include "bits/stdc++.h" 2 3 using namespace std; 4 5 inline int read(){ 6 int s=0,k=1;char ch=getchar (); 7 while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar(); 8 while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar(); 9 return s*k; 10 } 11 12 const int N=5e4+10; 13 14 typedef long long ll; 15 16 int Kd; 17 18 ll A,B,C,ans; 19 20 #define sum(x) (x?x->sum:0) 21 22 struct Point{ 23 int d[2],mx[2],mn[2],val; 24 Point *lc,*rc; 25 ll sum; 26 int& operator [](int k){ 27 return d[k]; 28 } 29 friend bool operator <(Point a,Point b){ 30 return a[Kd]<b[Kd]; 31 } 32 inline void update(){ 33 for (int i=0;i<2;++i) { 34 mx[i]=mn[i]=d[i]; 35 if(lc) mx[i]=max(mx[i],lc->mx[i]),mn[i]=min(mn[i],lc->mn[i]); 36 if(rc) mx[i]=max(mx[i],rc->mx[i]),mn[i]=min(mn[i],rc->mn[i]); 37 } 38 sum=val+sum(lc)+sum(rc); 39 } 40 }cho[N]; 41 42 #define check(x,y) (A*x+B*y<C) 43 44 inline int calc(Point x){ 45 int ret=0; 46 ret=check(x.mn[0],x.mn[1])+check(x.mx[0],x.mx[1]) 47 +check(x.mn[0],x.mx[1])+check(x.mx[0],x.mn[1]); 48 return ret; 49 } 50 51 struct KdTree{ 52 inline Point* build(int l,int r,int now){ 53 Kd=now;int mid=l+r>>1; 54 nth_element(cho+l,cho+mid,cho+r+1); 55 Point *t=&cho[mid]; 56 if(l^mid) t->lc=build(l,mid-1,now^1); 57 if(r^mid) t->rc=build(mid+1,r,now^1); 58 t->update(); 59 return t; 60 } 61 inline void query(Point *t){ 62 if (check(t->d[0],t->d[1])) ans+=t->val; 63 int tl=0,tr=0; 64 if(t->lc) tl=calc(*(t->lc)); 65 if(t->rc) tr=calc(*(t->rc)); 66 if(tl&4) ans+=t->lc->sum; 67 else if(tl) query(t->lc); 68 if(tr&4) ans+=t->rc->sum; 69 else if(tr) query(t->rc); 70 } 71 72 }kd; 73 74 int n,m; 75 76 int main(){ 77 n=read(),m=read(); 78 register int i,j; 79 for (i=1;i<=n;++i) 80 cho[i][0]=read(),cho[i][1]=read(), 81 cho[i].val=read(); 82 Point *root=kd.build(1,n,0); 83 while (m--){ 84 A=read(),B=read(),C=read(); 85 ans=0; 86 kd.query(root); 87 printf("%lld\n",ans); 88 } 89 }
没有什么不可能。