zoukankan      html  css  js  c++  java
  • 洛谷 P1503 鬼子进村(平衡树)

    传送门


    解题思路

    用平衡树维护摧毁的房屋。
    摧毁等于insert,修复等于delete,询问等于查询前驱后继。
    为了方便先扔进一个0点和n+1点。
    注意查询时先进行判断当前房屋是否已经摧毁。

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<bitset>
    #include<stack>
    using namespace std;
    const int maxn=5e4+5;
    int n,m,cnt,vis[maxn],rt;
    struct node{
    	int fa,val,son[2];
    }tr[maxn];
    int New(int val,int fa){
    	cnt++;
    	tr[cnt].fa=fa;
    	tr[cnt].val=val;
    	tr[cnt].son[0]=tr[cnt].son[1]=0;
    	return cnt;
    }
    void Del(int x){
    	tr[x].fa=tr[x].val=tr[x].son[0]=tr[x].son[1]=0;
    }
    void rotate(int x){
    	int y=tr[x].fa,z=tr[y].fa;
    	int c=(tr[y].son[1]==x);
    	tr[x].fa=z;
    	tr[y].fa=x;
    	if(tr[x].son[!c]) tr[tr[x].son[!c]].fa=y;
    	tr[y].son[c]=tr[x].son[!c];
    	tr[x].son[!c]=y;
    	if(z) tr[z].son[tr[z].son[1]==y]=x;
    }
    void splay(int x,int goal){
    	if(x==goal) return;
    	while(tr[x].fa!=goal){
    		int y=tr[x].fa,z=tr[y].fa;
    		if(z!=goal) ((tr[y].son[0]==x)^(tr[z].son[0]==y))?rotate(x):rotate(y);
    		rotate(x);
    	}
    	if(!goal) rt=x;
    }
    void insert(int val){
    	if(!rt){
    		rt=New(val,0);
    		return;
    	}
    	int x=rt;
    	while(1){
    		if(tr[x].son[tr[x].val<val]) x=tr[x].son[tr[x].val<val];
    		else{
    			tr[x].son[tr[x].val<val]=New(val,x);
    			splay(cnt,0);
    			return;
    		}
    	}
    }
    int pre(){
    	int x=tr[rt].son[0];
    	while(tr[x].son[1]) x=tr[x].son[1];
    	return x;
    }
    int nxt(){
    	int x=tr[rt].son[1];
    	while(tr[x].son[0]) x=tr[x].son[0];
    	return x;
    }
    void del(int x){
    	splay(x,0);
    	int rt=pre();
    	splay(rt,0);
    	splay(x,rt);
    	tr[rt].son[1]=tr[x].son[1];
    	if(tr[x].son[1]) tr[tr[x].son[1]].fa=rt;
    	Del(x);
    }
    int main(){
    	ios::sync_with_stdio(false);
    	cin>>n>>m;
    	insert(0);
    	insert(n+1);
    	for(int i=1;i<=m;i++){
    		char op;cin>>op;
    		if(op=='D'){
    			int x;
    			cin>>x;
    			insert(x);
    			vis[x]=1;
    		}else{
    			if(op=='R'){
    				vis[tr[cnt].val]=0;
    				del(cnt--);
    			}else{
    				int x;
    				cin>>x;
    				if(vis[x]) cout<<0<<endl;
    				else insert(x),cout<<tr[nxt()].val-tr[pre()].val-1<<endl,del(cnt--);
    			}
    		}
    	} 
    	return 0;
    }
    
  • 相关阅读:
    Orcle数据库查询练习复习:二
    Orcle数据库查询练习复习:一
    Xamarin.Android 入门之:xamarin使用webserver和html交互
    Xamarin.Android 入门之:Listview和adapter
    Xamarin.Android 入门之:Android的生命周期
    Xamarin.Android 入门之:Android API版本设置
    Xamarin.Android 入门之:Xamarin快速入门
    阶段01Java基础day16集合框架02
    阶段01Java基础day13常见对象02
    阶段01Java基础day10面向对象05
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15519940.html
Copyright © 2011-2022 走看看