洛谷P2286宠物收养场·改

#include<cstdio>
#define abs(a,b) (a>b?a-b:b-a)
#define MOD 1000000
#define MXN 80000+5
int read(){
    int x=0,w=1;
    char c=getchar();
    while(c<‘0‘||c>‘9‘){
        if(c==‘-‘) w=-1;
        c=getchar();
    }
    while(c>=‘0‘&&c<=‘9‘){
        x=(x<<3)+(x<<1)+(c-‘0‘);
        c=getchar();
    }
    return x*w;
}
int ans;
struct Node{
    int val;
    bool type;
    Node *fa,*left,*right;
}node[MXN],*root,*recycle[MXN];
int n,p,x,node_num=-1,top=-1;
bool tree_type;
void rotate(Node *now){
    if(now->fa==NULL) return;
    Node *f,*gf,*l,*r;
    f=now->fa;
    gf=f->fa;
    l=now->left;
    r=now->right;
    now->fa=gf;
    if(gf!=NULL){
        if(gf->left==f) gf->left=now;
        if(gf->right==f) gf->right=now;
    }
    if(f->left==now){
        now->right=f;
        f->left=r;
        if(r!=NULL) r->fa=f;
    }
    if(f->right==now){
        now->left=f;
        f->right=l;
        if(l!=NULL) l->fa=f;
    }
    f->fa=now;
    if(now->fa==NULL) root=now;
    return;
}
void splay(Node *now,Node *des){
    if(now==des) return;
    Node *f,*gf;
    while(now->fa!=des){
        f=now->fa;
        gf=f->fa;
        if(gf==des) rotate(now);
        else if(gf->left==f&&f->right==now){
            rotate(now);
            rotate(now);
        }
        else if(gf->right==f&&f->left==now){
            rotate(now);
            rotate(now);
        }
        else if(gf->left==f&&f->left==now){
            rotate(f);
            rotate(now);
        }
        else if(gf->right==f&&f->right==now){
            rotate(f);
            rotate(now);
        }
    }
    if(now->fa==NULL) root=now;
    return;
}
Node* node_new(int vl,bool typ){
    Node *n;
    if(top!=-1){
        n=recycle[top];
        top--;
    }
    else{
        node_num++;
        n=&node[node_num];
    }
    n->val=vl;
    n->type=typ;
    n->left=NULL;
    n->right=NULL;
    n->fa=NULL;
    return n;
}
void node_insert(Node *now,Node *v){
    if(root==NULL){
        root=v;
        tree_type=v->type;
        return;
    }
    if(now==NULL){
        *now=*v;
        return;
    }
    if(v->val<=now->val){
        if(now->left==NULL){
            now->left=v;
            v->fa=now;
        }
        else node_insert(now->left,v);
    }
    if(v->val>now->val){
        if(now->right==NULL){
            now->right=v;
            v->fa=now;
        }
        else node_insert(now->right,v);
    }
    splay(v,NULL);
    return;
}
Node* root_prev(){
    Node *t;
    if(root->left!=NULL){
        t=root->left;
        while(t->right!=NULL) t=t->right;
        return t;
    }
    else return NULL;
}
Node* root_subs(){
    Node *t;
    if(root->right!=NULL){
        t=root->right;
        while(t->left!=NULL) t=t->left;
        return t;
    }
    else return NULL;
}
void node_delete(Node *now){
    recycle[++top]=now;
    splay(now,NULL);
    root=now;
    if(now->left==NULL&&now->right==NULL){
        root=NULL;
        return;
    }
    if(now->left==NULL){
        root=now->right;
        root->fa=NULL;
        return;
    }
    if(now->right==NULL){
        root=now->left;
        root->fa=NULL;
        return;
    }
    Node *l,*r;
    l=now->left;
    r=now->right;
    l->fa=NULL;
    Node *t=now->left;
    while(t->right!=NULL) t=t->right;
    splay(t,NULL);
    t->right=r;
    r->fa=t;
    root=t;
    return;
}
void ques(Node *now){
    node_insert(root,now);
    if(now->type==tree_type) return;
    else{
        splay(now,NULL);
        Node *p,*s,*a;
        p=root_prev();
        s=root_subs();
        a=p;
        int t1,t2;
        if(p!=NULL) t1=abs(p->val,now->val);
        else t1=1<<30;
        if(s!=NULL) t2=abs(s->val,now->val);
        else t2=1<<30;
        if(t2<t1){
            a=s;
            ans+=t2;
        }
        else ans+=t1;
        ans%=MOD;
        node_delete(now);
        node_delete(a);
    }
    return;
}
int main(){
    root=NULL;
    n=read();
    for(int i=0;i<n;i++){
        p=read();
        x=read();
        ques(node_new(x,(bool)p));
    }
    printf("%d",ans);
    return 0;
}

优化代码

这次修改了一下上次写的代码。

由于本人建树的方法属于静态分配内存(动态分配总会出现玄学错误...),因此内存空间要开很大很大才不会RE,删除节点后,上一次的代码没有垃圾回收,导致空间复杂度稍大(上一次大约O(5n)才过去)。

这次开了一个栈,命名为recycle回收站,每次删除节点后,地址丢到回收站,创造新节点时,先检查回收站里有没有空闲地址,有就用,没有才在静态内存空间里找一个地址分配。这样空间复杂度变为了O(2n),降低了很多(实际上从4.31MB降到了2.21MB)。

不过感觉回头还是学一下动态分配吧...

时间: 2024-11-12 15:17:45

洛谷P2286宠物收养场·改的相关文章

洛谷P2286宠物收养场

1 #include<cstdio> 2 #define abs(a,b) (a>b?a-b:b-a) 3 #define MOD 1000000 4 #define MXN 450000+5 5 int read(){ 6 int x=0,w=1; 7 char c=getchar(); 8 while(c<'0'||c>'9'){ 9 if(c=='-') w=-1; 10 c=getchar(); 11 } 12 while(c>='0'&&c&l

宠物收养场 Treap

宠物收养场 时间限制: 1 Sec  内存限制: 128 MB 题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养场的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养场总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少.

[HNOI 2004]宠物收养场

Description 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养场的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养场总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 被遗弃的宠物过多时,假若到来一个领养者,这个领养

[HNOI2004]宠物收养场——treap

凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养场的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养场总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 被遗弃的宠物过多时,假若到来一个领养者,这个领养者希望领养的宠物的特点值

1208. [HNOI2004]宠物收养场【平衡树-splay】

Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 1. 被遗弃的宠物过多时,假若到来一个领养者

HNOI2004 宠物收养场 [Treap]

题面传送门戳我 Treap计算前驱/后继. 直接搞两个Treap,一个维护宠物,一个维护收养人. 如果输入人,并且宠物Treap不为空,直接查询一下,然后删除.否则插入人Treap. 宠物同理. 但是在查询Treap是否为空的时候不能直接写if(root[x]->size==0)因为这个时候有可能Treap为空,就会RE. 所以要这么写if(root[x]==NULL || root[x]->size==0),因为if语句有个机制,它会先判断前面的条件,如果前面的条件满足就不会去判断后面的..

[题解]洛谷比赛『期末考后的休闲比赛2』

[前言] 这场比赛已经结束了有几天,但我各种忙,虽然AK但还是没来得及写题解.(我才不会告诉你我跑去学数据结构了) T1 区间方差 (就不贴题好了) 首先可以推公式(我们可以知道,线段树然而并不能通过初中学过的方差公式在log(L)内求出方差): (s2表示方差,L表示区间长度,xi表示区间的每一项,最后一个x上画了一根线表示这些数据的平均数) 用二项式定理完全平方公式可得: 再次展开: 另外,再代入以下这个 得到了: 然后继续吧.. 然后duang地一声合并同类项,于是我们得到了: 然后可以高

洛谷P1650赛马与codevs 2181 田忌赛马

洛谷P1650 赛马 题目描述 我国历史上有个著名的故事: 那是在2300年以前.齐国的大将军田忌喜欢赛马.他经常和齐王赛马.他和齐王都有三匹马:常规马,上级马,超级马.一共赛三局,每局的胜者可以从负者这里取得200银币.每匹马只能用一次.齐王的马好,同等级的马,齐王的总是比田忌的要好一点.于是每次和齐王赛马,田忌总会输600银币. 田忌很沮丧,直到他遇到了著名的军师――孙膑.田忌采用了孙膑的计策之后,三场比赛下来,轻松而优雅地赢了齐王200银币.这实在是个很简单的计策.由于齐王总是先出最好的马

洛谷1231 教辅的组成

洛谷1231 教辅的组成 https://www.luogu.org/problem/show?pid=1231 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书多得数不胜数,其中有书,有答案,有练习册.已知一个完整的书册均应该包含且仅包含一本书.一本练习册和一份答案,然而现在全都乱做了一团.许多书上面的字迹都已经模糊了,然而HansBug还是可