BZOJ2850: 巧克力王国

来源:互联网 发布:西安交通大学网络缴费 编辑:程序博客网 时间:2024/04/29 06:15

KD树裸题

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

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

#include<cstdio>#include<iostream>#include<cstring>#include<ctime>#include<algorithm>using namespace std;#define ll long longchar 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;}
0 0
原创粉丝点击