BZOJ2850: 巧克力王国

KD树裸题

很久以前就会打了但是一直没遇到裸题
今天刚好交一发

感觉不是很懂删除的那一套理论QWQ

#include<cstdio>
#include<iostream>
#include<cstring>
#include<ctime>
#include<algorithm>
using namespace std;
#define ll long long
char c;
bool flag;
inline void read(int&a)
{
    a=0;do c=getchar();while(c!='-'&&(c>'9'||c<'0'));
    if(c=='-')c=getchar(),flag=true;
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
    if(flag)a=-a,flag=false;
}
inline void read(ll&a)
{
    a=0;do c=getchar();while(c!='-'&&(c>'9'||c<'0'));
    if(c=='-')c=getchar(),flag=true;
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
    if(flag)a=-a,flag=false;
}
const
 int INF=1<<29;
int f;
struct KD
{
    KD*lc,*rc;
    int Val;
    int X[2],Max[2],Min[2];
    int op;
    ll sum;
    inline int & operator [](int x){return X[x];}
    inline friend bool operator <(KD a,KD b){return a[f]<b[f];}
};
struct XA
{
  int X[2];
  int Val;
  inline int & operator [](int x){return X[x];} 
  inline friend bool operator <(XA a,XA b){return a[f]<b[f];}
};
XA Q[100001];
ll Calc(int l,int r)
{
   int base=0;
   ll res=0;
   for(int i=l;i<=r;i++)base+=Q[i][f];
   base/=(r-l+1);
   for(int i=l;i<=r;i++)res+=(Q[i][f]-base)*(Q[i][f]-base);
  return res;
}

KD*build(int l,int r)
{
  if(l>r)return NULL;
  f=0;
  ll a=Calc(l,r);
  f=1;
  if(a>Calc(l,r))f=0;

  sort(Q+l,Q+1+r);
  int mid=(l+r)>>1;
    KD*E=new KD;
    E->op=f;
    E->Val=Q[mid].Val;
    E->X[1]=Q[mid][1];
    E->X[0]=Q[mid][0];
    E->lc=build(l,mid-1);
    E->rc=build(mid+1,r);
    E->sum=(E->lc==NULL?0:E->lc->sum)+(E->rc==NULL?0:E->rc->sum)+Q[mid].Val;
    E->Max[0]=max(max((E->lc==NULL?-INF:E->lc->Max[0]),(E->rc==NULL?-INF:E->rc->Max[0])),Q[mid].X[0]);
    E->Max[1]=max(max((E->lc==NULL?-INF:E->lc->Max[1]),(E->rc==NULL?-INF:E->rc->Max[1])),Q[mid].X[1]);
    E->Min[0]=min(min((E->lc==NULL?INF:E->lc->Min[0]),(E->rc==NULL?INF:E->rc->Min[0])),Q[mid].X[0]);
    E->Min[1]=min(min((E->lc==NULL?INF:E->lc->Min[1]),(E->rc==NULL?INF:E->rc->Min[1])),Q[mid].X[1]);
    return E;
}

ll A,B,C,ans;
#define estimate(x,y) (A*(x)+B*(y)<C)
#define C(x) (estimate((x).Max[0],(x).Min[1])+estimate((x).Min[0],(x).Max[1])+estimate((x).Max[0],(x).Max[1])+estimate((x).Min[0],(x).Min[1]))
int n,m;
void Query(KD*Cur)
{
  KD*LC=Cur->lc,*RC=Cur->rc;
  if(estimate(Cur->X[0],Cur->X[1]))ans+=Cur->Val;
  int d=0;
  if(LC&&(d=C(*LC))==4)
    ans+=LC->sum;
    else if(d)Query(LC);
  d=0;
  if(RC&&(d=C(*RC))==4)ans+=RC->sum;
    else if(d)Query(RC);
}

int main()
{
    read(n),read(m);
    for(int i=1;i<=n;i++)   
         read(Q[i][0]),read(Q[i][1]),read(Q[i].Val);
    KD*R=build(1,n);
    while(m--)
    {
        read(A),read(B),read(C);
        ans=0;
        Query(R);
        printf("%lld\n",ans);
    }
    return 0;
}

你可能感兴趣的:(BZOJ2850: 巧克力王国)