zoukankan      html  css  js  c++  java
  • 【kd-tree】bzoj2850 巧克力王国

    分四种情况讨论:a,b>=0

    a,b<0

    a>=0,b<0

    a<0,b>=0

    然后每次检验是否进入一个矩形框 或者 是否直接利用这个矩形框的答案 仅仅利用两个对角的坐标进行更新即可。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    #define N 50001
    #define INF 2147483647
    #define KD 2//ά¶ÈÊý
    int qp[KD];
    ll lim;
    int n,root,m;
    bool dn;
    struct Node
    {
        int minn[KD],maxx[KD],p[KD],w;
        int ch[2];
        ll sumv;
        void Init()
          {
            for(int i=0;i<KD;++i)
              minn[i]=maxx[i]=p[i];
            sumv=(ll)w;
          }
    }T[N];
    void Update(int rt)
    {
        for(int i=0;i<2;++i)
          if(T[rt].ch[i])
            {
              T[rt].sumv+=T[T[rt].ch[i]].sumv;
              for(int j=0;j<KD;++j)
                {
                  T[rt].minn[j]=min(T[rt].minn[j],T[T[rt].ch[i]].minn[j]);
                  T[rt].maxx[j]=max(T[rt].maxx[j],T[T[rt].ch[i]].maxx[j]);
                }
            }
    }
    bool operator < (const Node &a,const Node &b){return a.p[dn]<b.p[dn];}
    int Buildtree(int l=1,int r=n,bool d=0)
    {
        dn=d;
        int m=(l+r>>1);
        nth_element(T+l,T+m,T+r+1);
        T[m].Init();
        if(l!=m) T[m].ch[0]=Buildtree(l,m-1,d^1);
        if(m!=r) T[m].ch[1]=Buildtree(m+1,r,d^1);
        Update(m);
        return m;
    }
    ll ans;
    void Query0(int rt=root)//a>0,b>0
    {
        if((ll)T[rt].p[0] * (ll)qp[0] + (ll)T[rt].p[1] * (ll)qp[1] < lim)
          ans+=(ll)T[rt].w;
        for(int i=0;i<2;++i)
          if(T[rt].ch[i] &&
          (ll)T[T[rt].ch[i]].minn[0] * (ll)qp[0] +
          (ll)T[T[rt].ch[i]].minn[1] * (ll)qp[1] < lim)
            {
              if((ll)T[T[rt].ch[i]].maxx[0] * (ll)qp[0] +
              (ll)T[T[rt].ch[i]].maxx[1] * (ll)qp[1] < lim)
                ans+=T[T[rt].ch[i]].sumv;
              else
                Query0(T[rt].ch[i]);
            }
    }
    void Query1(int rt=root)//a>0,b<0
    {
        if((ll)T[rt].p[0] * (ll)qp[0] + (ll)T[rt].p[1] * (ll)qp[1] < lim)
          ans+=(ll)T[rt].w;
        for(int i=0;i<2;++i)
          if(T[rt].ch[i] &&
          (ll)T[T[rt].ch[i]].minn[0] * (ll)qp[0] +
          (ll)T[T[rt].ch[i]].maxx[1] * (ll)qp[1] < lim)
            {
              if((ll)T[T[rt].ch[i]].maxx[0] * (ll)qp[0] +
              (ll)T[T[rt].ch[i]].minn[1] * (ll)qp[1] < lim)
                ans+=T[T[rt].ch[i]].sumv;
              else
                Query1(T[rt].ch[i]);
            }
    }
    void Query2(int rt=root)//a<0,b>0
    {
        if((ll)T[rt].p[0] * (ll)qp[0] + (ll)T[rt].p[1] * (ll)qp[1] < lim)
          ans+=(ll)T[rt].w;
        for(int i=0;i<2;++i)
          if(T[rt].ch[i] &&
          (ll)T[T[rt].ch[i]].maxx[0] * (ll)qp[0] +
          (ll)T[T[rt].ch[i]].minn[1] * (ll)qp[1] < lim)
            {
              if((ll)T[T[rt].ch[i]].minn[0] * (ll)qp[0] +
              (ll)T[T[rt].ch[i]].maxx[1] * (ll)qp[1] < lim)
                ans+=T[T[rt].ch[i]].sumv;
              else
                Query2(T[rt].ch[i]);
            }
    }
    void Query3(int rt=root)//a<0,b<0
    {
        if((ll)T[rt].p[0] * (ll)qp[0] + (ll)T[rt].p[1] * (ll)qp[1] < lim)
          ans+=(ll)T[rt].w;
        for(int i=0;i<2;++i)
          if(T[rt].ch[i] &&
          (ll)T[T[rt].ch[i]].maxx[0] * (ll)qp[0] +
          (ll)T[T[rt].ch[i]].maxx[1] * (ll)qp[1] < lim)
            {
              if((ll)T[T[rt].ch[i]].minn[0] * (ll)qp[0] +
              (ll)T[T[rt].ch[i]].minn[1] * (ll)qp[1] < lim)
                ans+=T[T[rt].ch[i]].sumv;
              else
                Query3(T[rt].ch[i]);
            }
    }
    int main()
    {
    //  freopen("bzoj2850.in","r",stdin);
    //  freopen("bzoj2716.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
          scanf("%d%d%d",&T[i].p[0],&T[i].p[1],&T[i].w);
        Buildtree();
        root=(1+n>>1);
        for(int i=1;i<=m;++i)
          {
            ans=0;
            scanf("%d%d%lld",&qp[0],&qp[1],&lim);
            if(qp[0]>=0 && qp[1]>=0)
              Query0();
            else if(qp[0]>=0 && qp[1]<0)
              Query1();
            else if(qp[0]<0 && qp[1]>=0)
              Query2();
            else
              Query3();
            printf("%lld
    ",ans);
          }
        return 0;
    }
  • 相关阅读:
    如何通过转换例程加减前导0
    PA教材提纲 TAW12-2
    Web开发框架趋势
    ASP.NET MVC
    一步步实现Promise
    在Jenkins中使用Git Plugin访问Https代码库失败的问题
    5年从DBA到运维架构总监 — 做对了什么
    Hello又大了一岁
    JavaWeb限流QPS简易框架
    JAVA异常使用_每个人都曾用过、但未必都用得好
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4587118.html
Copyright © 2011-2022 走看看