bzoj 1208 宠物收养所 splay

链接 : http://www.lydsy.com/JudgeOnline/problem.php?id=1208

找前驱 后继 删除一个节点
直接将要删除的节点旋转到根,然后删除根节点即可

/**************************************************************
    Problem: 1208
    User: wuyiqi
    Language: C++
    Result: Accepted
    Time:216 ms
    Memory:5500 kb
找前驱 后继 删除一个节点
直接将要删除的节点旋转到根,然后删除根节点即可
****************************************************************/
#include<cstdio>
#include<cstdlib>
const int mod =1000000;
const int inf  = ~0u>>2;
#define KT (ch[ ch[rt][1] ][0])
const int maxn = 200010;
int lim;
struct SplayTree {
    int sz[maxn];
    int ch[maxn][2];
    int pre[maxn];
    int rt,top;
    inline void up(int x){
        sz[x]  = cnt[x]  + sz[ ch[x][0] ] + sz[ ch[x][1] ];
    }
    inline void Rotate(int x,int f){
        int y=pre[x];
        ch[y][!f] = ch[x][f];
        pre[ ch[x][f] ] = y;
        pre[x] = pre[y];
        if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;
        ch[x][f] = y;
        pre[y] = x;
        up(y);
    }
    inline void Splay(int x,int goal){//将x旋转到goal的下面
        while(pre[x] != goal){
            if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x);
            else   {
                int y=pre[x],z=pre[y];
                int f = (ch[z][0]==y);
                if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);
                else Rotate(y,f),Rotate(x,f);
            }
        }
        up(x);
        if(goal==0) rt=x;
    }
    inline void RTO(int k,int goal){//将第k位数旋转到goal的下面
        int x=rt;
        while(sz[ ch[x][0] ] != k-1) {
            if(k < sz[ ch[x][0] ]+1) x=ch[x][0];
            else {
                k-=(sz[ ch[x][0] ]+1);
                x = ch[x][1];
            }
        }
        Splay(x,goal);
    }
    inline void vist(int x){
        if(x){
            printf("结点%2d : 左儿子  %2d   右儿子  %2d   %2d sz=%d\n",x,ch[x][0],ch[x][1],val[x],sz[x]);
            vist(ch[x][0]);
            vist(ch[x][1]);
        }
    }
    inline void Newnode(int &x,int c){
        x=++top;
        ch[x][0] = ch[x][1] = pre[x] = 0;
        sz[x]=1; cnt[x]=1;
        val[x] = c;
    }
    inline void init(){
        ans=0;type=-1;
        ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;
        rt=top=0; cnt[0]=0;
        Newnode(rt,-inf);
        Newnode(ch[rt][1],inf);
        pre[top]=rt;
        sz[rt]=2;
    }
    inline void Insert(int &x,int key,int f){
        if(!x) {
            Newnode(x,key);
            pre[x]=f;
            Splay(x,0);
            return ;
        }
        if(key==val[x]){
            cnt[x]++;
            sz[x]++;
            return ;
        }else if(key<val[x]) {
            Insert(ch[x][0],key,x);
        } else {
            Insert(ch[x][1],key,x);
        }
        up(x);
    }
    void Del(){
	     int t=rt;
		 if(ch[rt][1]) {
			 rt=ch[rt][1];
			 RTO(1,0);
			 ch[rt][0]=ch[t][0];
			 if(ch[rt][0]) pre[ch[rt][0]]=rt;
		 }
		 else rt=ch[rt][0];
		 pre[rt]=0;
		 up(rt);
	}
    void findpre(int x,int key,int &ans){
        if(!x)  return ;
        if(val[x] <= key){
            ans=x;
            findpre(ch[x][1],key,ans);
        } else
            findpre(ch[x][0],key,ans);
    }
    void findsucc(int x,int key,int &ans){
        if(!x) return ;
        if(val[x]>=key) {
            ans=x;
            findsucc(ch[x][0],key,ans);
        } else
            findsucc(ch[x][1],key,ans);
    }
    void solve() {
        int a,b,x,y;
        scanf("%d%d",&a,&b);
        if(a==type || sz[rt]==2){
             
            Insert(rt,b,0),type=a;
            //printf("type=%d\n",type);
        }
        else {
            findpre(rt,b,x);
            findsucc(rt,b,y);
            if(abs(val[x]-b) <= abs(val[y]-b)) {
                ans+=abs(val[x]-b);
                ans%=mod;
				Splay(x,0);
                Del();
            }
            else {
                ans+=abs(val[y]-b);
                ans%=mod;
				Splay(y,0);
                Del();
            }
        }
        //spt.vist(rt);
    }
    int cnt[maxn];
    int val[maxn];
    int type;
    int ans;
}spt;
int main()
{
    int n;
    scanf("%d",&n);
    spt.init();
    while(n--)  spt.solve();
    printf("%d\n",spt.ans);
    return 0;
}


BZOJ 2908 题目是一个数据下载任务。这个任务要求下载指定的数据文件,并统计文件中小于等于给定整数的数字个数。 为了完成这个任务,首先需要选择一个合适的网址来下载文件。我们可以使用一个网络爬虫库,如Python中的Requests库,来帮助我们完成文件下载的操作。 首先,我们需要使用Requests库中的get()方法来访问目标网址,并将目标文件下载到我们的本地计算机中。可以使用以下代码实现文件下载: ```python import requests url = '目标文件的网址' response = requests.get(url) with open('本地保存文件的路径', 'wb') as file: file.write(response.content) ``` 下载完成后,我们可以使用Python内置的open()函数打开已下载的文件,并按行读取文件内容。可以使用以下代码实现文件内容读取: ```python count = 0 with open('本地保存文件的路径', 'r') as file: for line in file: # 在这里实现对每一行数据的判断 # 如果小于等于给定整数,count 加 1 # 否则,不进行任何操作 ``` 在每一行的处理过程中,我们可以使用split()方法将一行数据分割成多个字符串,并使用int()函数将其转换为整数。然后,我们可以将该整数与给定整数进行比较,以判断是否小于等于给定整数。 最后,我们可以将统计结果打印出来,以满足题目的要求。 综上所述,以上是关于解决 BZOJ 2908 数据下载任务的简要步骤和代码实现。 希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值