• bzoj 2850 巧克力王国——KDtree


    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2850

    改一下估价即可。判断子树能否整个取或者是否整个不能取,时间好像就能行了?

    因为有负数,所以判一下四个边界。注意这个区域本身还占了一个点。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=5e4+5;
    int n,m,rt,tot,fx;
    ll A,B,C;
    struct Dt{
        ll x[2],y[2],p[2],h,ph;
    }a[N];
    bool cmp(Dt u,Dt v){return u.p[fx]<v.p[fx];}
    struct KD{
        int c[N][2];Dt s[N];
        void add(int cr,Dt k)
        {
            for(int i=0;i<=1;i++) s[cr].x[i]=s[cr].y[i]=s[cr].p[i]=k.p[i];
            s[cr].h=s[cr].ph=k.h;
        }
        void pshp(int cr)
        {
            int ls=c[cr][0],rs=c[cr][1];
            for(int i=0;i<=1;i++)
            {
                if(ls)  s[cr].x[i]=min(s[cr].x[i],s[ls].x[i]),
                        s[cr].y[i]=max(s[cr].y[i],s[ls].y[i]);
                if(rs)  s[cr].x[i]=min(s[cr].x[i],s[rs].x[i]),
                        s[cr].y[i]=max(s[cr].y[i],s[rs].y[i]);
            }
            s[cr].h=(ls?s[ls].h:0)+(rs?s[rs].h:0)+s[cr].ph;
        }
        void build(int &cr,int l,int r,bool now)
        {
            int mid=l+r>>1;  fx=now;  nth_element(a+l,a+mid,a+r+1,cmp);
            cr=++tot;  add(cr,a[mid]);
            if(l<mid) build(c[cr][0],l,mid-1,!now);
            if(mid<r) build(c[cr][1],mid+1,r,!now);
            pshp(cr);
    //        printf("cr=%d(x:%lld~%lld y:%lld~%lld h=%lld)
    ",cr,s[cr].x[0],
    //            s[cr].y[0],s[cr].x[1],s[cr].y[1],s[cr].h);
        }
        int check(int cr)
        {
            int ret=0;
            ret+=(A*s[cr].x[0]+B*s[cr].x[1]<C);
            ret+=(A*s[cr].x[0]+B*s[cr].y[1]<C);
            ret+=(A*s[cr].y[0]+B*s[cr].x[1]<C);
            ret+=(A*s[cr].y[0]+B*s[cr].y[1]<C);
            return ret;
        }
        ll query(int cr)
        {
            ll ret=(A*s[cr].p[0]+B*s[cr].p[1]<C?s[cr].ph:0);
            int ls=c[cr][0],rs=c[cr][1];
            int dl=(ls?check(ls):0),dr=(rs?check(rs):0);
    //        printf("cr=%d(x:%lld~%lld y:%lld~%lld h=%lld) dl=%d dr=%d
    "
    //            ,cr,s[cr].x[0],s[cr].y[0],s[cr].x[1],s[cr].y[1],s[cr].h,dl,dr);
            if(dl==4) ret+=s[ls].h;  else if(dl) ret+=query(ls);
            if(dr==4) ret+=s[rs].h;  else if(dr) ret+=query(rs);
            return ret;
        }
    }kd;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%lld%lld%lld",&a[i].p[0],&a[i].p[1],&a[i].h);
        kd.build(rt,1,n,0);
        for(int i=1;i<=m;i++)
        {
            scanf("%lld%lld%lld",&A,&B,&C);
            printf("%lld
    ",kd.query(rt));
        }
        return 0;
    }
  • 相关阅读:
    1.表单标签
    07.Ajax.post
    06.Ajax.get
    05.Ajax.get
    04.Ajax-get.html
    03.post.file
    nodejs-7.2. CURD数据管理系统小栗子
    nodejs-7.1. mongoose模块
    JS 无缝轮播图1-节点操作
    JS 放大镜特效
  • 原文地址:https://www.cnblogs.com/Narh/p/9600294.html
Copyright © 2020-2023  润新知