• 【kd-tree】bzoj3290 Theresa与数据结构


    离线所有操作,对所有可能存在的点建立kd-tree,add相当于权值+1,cancel相当于权值-1。

    修改操作要记录kd-tree上每个点的fa,从底向上地进行修改。

    优化:若一个矩形框的sumv==0,则不进入。记录矩形框的面积时只记录“有意义”的点的(权值为0的不管)。

    #include<cstdio>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    using namespace std;
    int f,C;
    inline void R(int &x){
        C=0;f=1;
        for(;C<'0'||C>'9';C=getchar())if(C=='-')f=-1;
        for(x=0;C>='0'&&C<='9';C=getchar())(x*=10)+=(C-'0');
        x*=f;
    }
    inline void P(int x){
        if(x<10)putchar(x+'0');
        else{P(x/10);putchar(x%10+'0');}
    }
    stack<int>zhan;
    #define N 100001
    #define KD 3
    int dn,n,root,m,qp[2][KD],idn;
    struct Node
    {
        int ch[2],w,minn[KD],maxx[KD],p[KD],sumv,id;
        void Init()
          {
            sumv=w;
            for(int i=0;i<KD;++i)
              minn[i]=maxx[i]=p[i];
          }
    }T[N];
    bool operator < (const Node &a,const Node &b){return a.p[dn] < b.p[dn];}
    inline void pushup(const int &rt)
    {
        T[rt].sumv=T[rt].w;
        for(int i=0;i<2;++i)
          if(T[rt].ch[i]/* && T[T[rt].ch[i]].sumv*/)
            {
              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]);
                }
            }
    }
    int buildtree(int l=1,int r=n,int 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)%KD);
        if(m!=r) T[m].ch[1]=buildtree(m+1,r,(d+1)%KD);
        pushup(m);
        return m;
    }
    inline bool Inside(const int &o)
    {
        for(int i=0;i<KD;++i)
          if(qp[0][i] > T[o].p[i] || T[o].p[i] > qp[1][i])
            return 0;
        return 1;
    }
    inline bool AllInside(const int &o)
    {
        for(int i=0;i<KD;++i)
          if(qp[0][i] > T[o].minn[i] || T[o].maxx[i] > qp[1][i])
            return 0;
        return 1;
    }
    inline bool Cross(const int &o)
    {
        for(int i=0;i<KD;++i)
          if(qp[0][i] > T[o].maxx[i] || T[o].minn[i] > qp[1][i])
            return 0;
        return 1;
    }
    int ans;
    inline void Query(int rt=root)
    {
        if(Inside(rt)) ans+=T[rt].w;
        for(int i=0;i<2;++i)
          if(T[rt].ch[i] && Cross(T[rt].ch[i]))
            {
              if(AllInside(T[rt].ch[i]))
                ans+=T[T[rt].ch[i]].sumv;
              else if(T[T[rt].ch[i]].sumv)
                Query(T[rt].ch[i]);
            }
    }
    int val;
    char op[N][7];
    int dian[N][KD],rs[N],ids[N],ma[N],fa[N];
    void Update()
    {
        int U=ma[idn];
        T[U].w+=val;
        T[U].sumv+=val;
        U=fa[U];
        while(U)
          {
            T[U].sumv=T[U].w+T[T[U].ch[0]].sumv+T[T[U].ch[1]].sumv;
    //      pushup(U);
            U=fa[U];
          }
    }
    int main()
    {
    //  freopen("theresa9.in","r",stdin);
    //  freopen("bzoj3290.out","w",stdout);
        R(n);
        for(int i=1;i<=n;++i)
          {
            R(T[i].p[0]); R(T[i].p[1]); R(T[i].p[2]);
            T[i].id=i;
            T[i].w=1;
          }
        R(m);
        for(int i=1;i<=m;++i)
          {
            scanf("%s",op[i]);
            if(op[i][0]=='A')
              {
                ++n;
                R(T[n].p[0]); R(T[n].p[1]); R(T[n].p[2]);
                T[n].id=n;
                ids[i]=n;
                zhan.push(n);
              }
            else if(op[i][0]=='Q')
              {
                R(dian[i][0]); R(dian[i][1]); R(dian[i][2]); R(rs[i]);
              }
            else
              {
                ids[i]=zhan.top();
                zhan.pop();
              }
          }
        root=(1+n>>1);
        buildtree();
        for(int i=1;i<=n;++i)
          {
            ma[T[i].id]=i;
            for(int j=0;j<2;++j)
              if(T[i].ch[j])
                fa[T[i].ch[j]]=i;
          }
        for(int i=1;i<=m;++i)
          if(op[i][0]=='A')
            {
              idn=ids[i];
              val=1;
              Update();
            }
          else if(op[i][0]=='Q')
            {
              memcpy(qp[0],dian[i],sizeof(qp[0]));
              for(int j=0;j<KD;++j)
                qp[1][j]=qp[0][j]+rs[i];
              ans=0;
              Query();
    //        printf("%d
    ",ans);
              P(ans),puts("");
            }
          else
            {
              idn=ids[i];
              val=-1;
              Update();
            }
        return 0;
    }
  • 相关阅读:
    湖南省第6届程序大赛第6题 Biggest Number
    湖南省第6届程序大赛第5题 内部收益率
    湖南省第6届程序大赛第4题 台球碰撞
    湖南省第6届程序大赛第3题 数字整除
    湖南省第6届程序大赛第二题 弟弟的作业
    湖南省第6届程序设计大赛第一题 汽水瓶
    Nginx 负载均衡配置
    Nginx 反向代理流程
    Nginx 对客户端请求的特殊处理
    Nginx文件操作的优化
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4587087.html
Copyright © 2020-2023  润新知