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); 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\n",x1,y1,ad);
        }
        else
        {
            x1=rand()%n; y1=rand()%n; x2=rand()%n; y2=rand()%n;
            printf("%d %d %d %d\n",x1,y1,x2,y2);
        }
    }
    printf("3\n");
    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)\n",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\n",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\n",
//            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)\n",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\n",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\n",cr,fa);
        cnt=0;  kill(cr);
//        if(debg<=50) printf("cnt=%d\n",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\n",ans);
        }
        if(R)
        {
            if(R==rt)fa=0;  kd.rebd(R); R=0;
        }
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/Narh/p/9605505.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: bzoj作为一个计算机竞赛的在线评测系统,不仅可以提供大量的目供程序员练习和学习,还可以帮助程序员提升算法和编程能力。为了更好地利用bzoj进行目的学习和刷,制定一个bzoj计划是非常有必要的。 首先,我们需要合理安排时间,每天留出一定的时间来做bzoj目。可以根据自己的时间安排,每天挑选适量的目进行解答。可以先从难度较低的目开始,逐渐提高难度,这样既能巩固基础知识,又能挑战自己的思维能力。 其次,要有一个计划和目标。可以规划一个每周或每月的目数量目标,以及每个阶段要学习和掌握的算法知识点。可以根据bzoj目分类,如动态规划、图论、贪心算法等,结合自己的实际情况,有针对性地选择目进行学习。 此外,要充分利用bzoj提供的资源。bzoj网站上有很多高质量的解和优秀的解代码,可以参考和学习。还有相关的讨论区,可以与其他程序员交流和讨论,共同进步。 最后,要坚持并保持思考。做不是单纯为了刷数量,更重要的是学会思考和总结。遇到难时,要有耐心,多思考,多尝试不同的解法。即使不能一次性解出来,也要学会思考和分析解过程,以及可能出现的错误和优化。 总之,bzoj计划的关键在于合理安排时间、制定目标、利用资源、坚持思考。通过有计划的刷,可以提高算法和编程能力,并培养解决问的思维习惯,在计算机竞赛中取得更好的成绩。 ### 回答2: bzoj计划是指在bzoj这个在线测评系统上制定一套学习和刷的计划,并且将计划记录在excel表格中。该计划主要包括以下几个方面的内容。 首先是学习目标的设定。通过分析自己的水平和知识缺口,可以设定一个合理的目标,比如每天解决一定数量的目或者提高特定的算法掌握程度。 其次是目选择的策略。在excel表格中可以记录下自己选择的目编号、目类型和难度等信息。可以根据目的类型和难度来安排每天的刷计划,确保自己可以逐步提高技巧和解能力。 然后是学习进度的记录和管理。将每天的完成情况记录在excel表格中,可以清晰地看到自己的学习进度和任务完成情况。可以使用图表等功能来对学习进度进行可视化展示,更好地管理自己的学习计划。 同时,可以在excel表格的备注栏中记录下每道目的解思路、关键点和需要复习的知识点等信息。这样可以方便自己回顾和总结,巩固所学的知识。 最后,可以将excel表格与其他相关资料进行整合,比如算法教材、目解析和学习笔记等。这样可以形成一个完整的学习档案,方便自己进行系统的学习和复习。 总之,bzoj计划excel的制定和记录可以帮助我们更加有条理和高效地进行学习和刷。通过合理安排学习目标和目选择策略,记录学习进度和思路,并整合其他学习资料,我们可以提高自己的解能力,并在bzoj上取得更好的成绩。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值