bzoj 4066 简单题——KDtree(带重构)

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

带部分重构的KDtree。就是那个替罪羊树思想的。

写了对拍,调了半天,发现忘了 rebd 里 fa==0 的时候改 rt !改后就能以一个很慢的速度A了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;
int n,m,k,op,x1,y1,x2,y2,ad;
int main()
{
    srand(time(0));
    n=rand()%(500000+1);printf("%d
",n); n++;
    m=rand()%(200000+1);
    k=1000000000-m;
    while(m--)
    {
        op=rand()%2+1; printf("%d ",op);
        if(op==1)
        {
            x1=rand()%n; y1=rand()%n; ad=rand()%k;
            printf("%d %d %d
",x1,y1,ad);
        }
        else
        {
            x1=rand()%n; y1=rand()%n; x2=rand()%n; y2=rand()%n;
            printf("%d %d %d %d
",x1,y1,x2,y2);
        }
    }
    printf("3
");
    return 0;
}
maker
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
    int cnt=0;
    while(1)
    {
        system("bzoj4066-maker.exe > bzoj4066-data.in");
        system("bzoj4066-zj.exe < bzoj4066-data.in > bzoj4066-zj.out");
        system("bzoj4066-baoli.exe < bzoj4066-data.in > bzoj4066-bl.out");
        if(system("fc bzoj4066-zj.out bzoj4066-bl.out"))
            return 0;
        cnt++; printf("(%d)
",cnt);
    }
    return 0;
}
duipai
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+5;
int n,x[N],y[N],h[N],x1,y1,x2,y2,tot,ans;
int rdn()
{
    int ret=0;char ch=getchar();
    while(ch>'9'||ch<'0') ch=getchar();
    while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
    return ret;
}
int main()
{
    n=rdn();
    while((n=rdn())!=3)
    {
        if(n==1)
        {
            x[++tot]=(rdn()^ans);y[tot]=(rdn()^ans);
            h[tot]=(rdn()^ans);
        }
        else
        {
            x1=(rdn()^ans);  y1=(rdn()^ans);
            x2=(rdn()^ans);  y2=(rdn()^ans);
            ans=0;
            for(int i=1;i<=tot;i++)
                if(x[i]>=x1&&x[i]<=x2&&y[i]>=y1&&y[i]<=y2) ans+=h[i];
            printf("%d
",ans);
        }
    }
    return 0;
}
baoli
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define db double
#define ls c[cr][0]
#define rs c[cr][1]
using namespace std;
const int N=2e5+5;  const db alpha=0.75;
int n,ans,rt,tot,fx,Q[N],top,R,fa,xf,cnt;
//int debg;
struct Dt{
    int x[2],y[2],p[2],siz,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],q;
    int New_node(){return top?Q[top--]:++tot;}
    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].ph=s[cr].h=k.ph;  s[cr].siz=1;
        ls=rs=0;
    }
    void pshp(int cr)
    {
        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;
        s[cr].siz=(ls?s[ls].siz:0)+(rs?s[rs].siz:0)+1;
    }
    bool check(int cr)
    { return (ls&&s[ls].siz>s[cr].siz*alpha)
                ||(rs&&s[rs].siz>s[cr].siz*alpha);}
    void insert(int &cr,int now)
    {
        if(!cr){ cr=New_node(); add(cr,q); return;}
        if(q.p[now]<=s[cr].p[now]) insert(ls,!now);
        else insert(rs,!now);
        pshp(cr);  if(check(cr)) R=cr,fx=now;
        if(R==ls) fa=cr,xf=0;  if(R==rs) fa=cr,xf=1;
    }
    bool Ok(int cr)
    {    return s[cr].p[0]>=q.x[0]&&s[cr].p[0]<=q.y[0]
                &&s[cr].p[1]>=q.x[1]&&s[cr].p[1]<=q.y[1];}
    int g(int cr)
    {
        int xmn=s[cr].x[0],xmx=s[cr].y[0],ymn=s[cr].x[1],ymx=s[cr].y[1];
        if(xmn>q.y[0]||xmx<q.x[0]||ymn>q.y[1]||ymx<q.x[1]) return 0;
        if(xmn>=q.x[0]&&xmx<=q.y[0]&&ymn>=q.x[1]&&ymx<=q.y[1]) return 2;
        return 1;
    }
    void query(int cr)
    {
        if(Ok(cr)) ans+=s[cr].ph;
        int dl=(ls?g(ls):0),dr=(rs?g(rs):0);
//        if(++debg<=50)printf("cr=%d(%d,%d) dl=%d dr=%d
",
//            cr,s[cr].p[0],s[cr].p[1],dl,dr);
        if(dl==2) ans+=s[ls].h;  else if(dl) query(ls);
        if(dr==2) ans+=s[rs].h;  else if(dr) query(rs);
    }
    void kill(int cr)
    {
        Q[++top]=cr;  a[++cnt]=s[cr];
//        if(debg<=50)
//            printf("kill cr=%d a=(%d,%d)
",cr,a[cnt].p[0],a[cnt].p[1]);
        if(ls)kill(ls);  if(rs)kill(rs);
    }
    void build(int &cr,int l,int r,int now)
    {
        int mid=l+r>>1; fx=now;  nth_element(a+l,a+mid,a+r+1,cmp);
        cr=New_node();  add(cr,a[mid]);
        if(l<mid) build(ls,l,mid-1,!now);
        if(mid<r) build(rs,mid+1,r,!now);
        pshp(cr);
//        if(debg<=50) printf("cr=%d x=%d~%d y=%d~%d
",cr,
//            s[cr].x[0],s[cr].y[0],s[cr].x[1],s[cr].y[1]);
    }
    void rebd(int cr)
    {
//        if(debg<=50)printf("rdbd! cr=%d fa=%d
",cr,fa);
        cnt=0;  kill(cr);
//        if(debg<=50) printf("cnt=%d
",cnt);
        int mid=1+cnt>>1;  nth_element(a+1,a+mid,a+cnt+1,cmp);
        cr=New_node();  add(cr,a[mid]);
        if(fa) c[fa][xf]=cr; else rt=cr;    ///rt=cr!!!
        int now=fx;
        if(1<mid) build(ls,1,mid-1,!now);
        if(mid<cnt) build(rs,mid+1,cnt,!now);
        pshp(cr);
    }
}kd;
int rdn()
{
    int ret=0;char ch=getchar();
    while(ch>'9'||ch<'0') ch=getchar();
    while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
    return ret;
}
int main()
{
    n=rdn();
    while((n=rdn())!=3)
    {
        if(n==1)
        {
            kd.q.p[0]=(rdn()^ans);  kd.q.p[1]=(rdn()^ans);
            kd.q.ph=(rdn()^ans);  fa=0;  kd.insert(rt,0);
        }
        else
        {
            kd.q.x[0]=(rdn()^ans);  kd.q.x[1]=(rdn()^ans);
            kd.q.y[0]=(rdn()^ans);  kd.q.y[1]=(rdn()^ans);
            ans=0;  kd.query(rt);  printf("%d
",ans);
        }
        if(R)
        {
            if(R==rt)fa=0;  kd.rebd(R); R=0;
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Narh/p/9605505.html