zoukankan      html  css  js  c++  java
  • bzoj 4066 & bzoj 2683 简单题 —— K-D树(含重构)

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

    https://www.lydsy.com/JudgeOnline/problem.php?id=2683

    高仿:https://www.cnblogs.com/Narh/p/9605505.html

    注意细节...

    AC 300 ~

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int const xn=2e5+5;
    double const alpha=0.75;
    int n,cnt,sta[xn],top,rt,dm,c[xn][2],qx1,qx2,qy1,qy2;
    int R,fa,son,num;
    ll ans;
    struct N{
      int x[2],y[2],p[2],siz;
      ll sum,ys;
    }t[xn],a[xn];
    int rd()
    {
      int ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    ll Abs(ll x){return x>0?x:-x;}
    ll Min(ll x,ll y){return x<y?x:y;}
    ll Max(ll x,ll y){return x<y?y:x;}
    bool cmp(N x,N y){return x.p[dm]<y.p[dm];}
    int node(){if(top)return sta[top--]; else return ++cnt;}
    void turn(int x,N v)
    {
      for(int i=0;i<2;i++)t[x].x[i]=t[x].y[i]=t[x].p[i]=v.p[i]; 
      t[x].ys=t[x].sum=v.ys; t[x].siz=1; c[x][0]=0; c[x][1]=0;//ys //c //v.ys!!!
    }
    void pushup(int x)
    {
      int ls=c[x][0],rs=c[x][1];
      for(int i=0;i<2;i++)
        {
          if(ls)t[x].x[i]=Min(t[x].x[i],t[ls].x[i]),t[x].y[i]=Max(t[x].y[i],t[ls].y[i]);
          if(rs)t[x].x[i]=Min(t[x].x[i],t[rs].x[i]),t[x].y[i]=Max(t[x].y[i],t[rs].y[i]);
        }
      t[x].sum=t[x].ys+(ls?t[ls].sum:0)+(rs?t[rs].sum:0);
      t[x].siz=1+(ls?t[ls].siz:0)+(rs?t[rs].siz:0);
    }
    bool ck(int x)
    {
      int ls=c[x][0],rs=c[x][1];
      return (ls&&t[ls].siz>t[x].siz*alpha)||(rs&&t[rs].siz>t[x].siz*alpha);
    }
    void ins(int &x,N v,int nw)
    {
      if(!x){x=node(); turn(x,v); return;}
      if(v.p[nw]<=t[x].p[nw])ins(c[x][0],v,nw^1);
      else ins(c[x][1],v,nw^1);
      pushup(x);
      if(ck(x))R=x,dm=nw;
      if(R==c[x][0])fa=x,son=0; if(R==c[x][1])fa=x,son=1;
    }
    bool can(int x)
    {return t[x].p[0]>=qx1&&t[x].p[0]<=qx2&&t[x].p[1]>=qy1&&t[x].p[1]<=qy2;}
    bool in(int x)
    {return t[x].x[0]>=qx1&&t[x].y[0]<=qx2&&t[x].x[1]>=qy1&&t[x].y[1]<=qy2;}
    bool out(int x)
    {return t[x].x[0]>qx2||t[x].y[0]<qx1||t[x].x[1]>qy2||t[x].y[1]<qy1;}
    ll query(int x)
    {
      if(can(x))ans+=t[x].ys;//ys
      int ls=c[x][0],rs=c[x][1];
      if(ls)
        {
          if(in(ls))ans+=t[ls].sum;
          else if(!out(ls))query(ls);
        }
      if(rs)
        {
          if(in(rs))ans+=t[rs].sum;
          else if(!out(rs))query(rs);
        }
    }
    void kill(int x)
    {
      sta[++top]=x; a[++num]=t[x];
      if(c[x][0])kill(c[x][0]);
      if(c[x][1])kill(c[x][1]);
    }
    void build(int &x,int l,int r,int nw)
    {
      x=node(); dm=nw; int mid=((l+r)>>1);
      nth_element(a+l,a+mid,a+r+1,cmp);
      turn(x,a[mid]);
      if(mid>l)build(c[x][0],l,mid-1,nw^1);
      if(mid<r)build(c[x][1],mid+1,r,nw^1);
      pushup(x);
    }
    void rbuild(int x)
    {
      num=0; kill(x); int mid=((1+num)>>1);
      nth_element(a+1,a+mid,a+num+1,cmp);
      int p=node(); turn(p,a[mid]);
      if(fa)c[fa][son]=p; else rt=p;//
      if(mid>1)build(c[p][0],1,mid-1,dm^1);
      if(mid<num)build(c[p][1],mid+1,num,dm^1);
      pushup(p);
    }
    int main()
    {
      n=rd(); N tmp;
      while((n=rd())!=3)
        {
          if(n==1)
    	{
    	  //tmp.p[0]=(rd()^ans); tmp.p[1]=(rd()^ans); tmp.ys=(rd()^ans);
    	  tmp.p[0]=rd(); tmp.p[1]=rd(); tmp.ys=rd();
    	  fa=0; ins(rt,tmp,0);//fa
    	}
          else
    	{
    	  //qx1=(rd()^ans); qy1=(rd()^ans);
    	  //qx2=(rd()^ans); qy2=(rd()^ans);
    	  qx1=rd(); qy1=rd(); qx2=rd(); qy2=rd();
    	  ans=0; query(rt); printf("%lld
    ",ans);
    	}
          if(R){if(R==rt)fa=0; rbuild(R); R=0;}
        }
      return 0;
    }
    
  • 相关阅读:
    一篇图看清Java中的各种Queue
    使用尾递归计算阶乘
    使用 Sonar 检测代码质量
    jsessionid 导致重定向404的问题
    Java8之——简洁优雅的Lambda表达式
    支付宝手机网站支付开发指引
    Intellij Idea 编辑器使用之 安装、破解 版本15.0.1
    虚拟机启动linux系统报错,此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态
    META-INF文件夹是干啥的,META-INF文件夹的作用, META-INF文件夹能删吗
    一道Integer面试题引发的对Integer的探究
  • 原文地址:https://www.cnblogs.com/Zinn/p/10153450.html
Copyright © 2011-2022 走看看