zoukankan      html  css  js  c++  java
  • 【BZOJ 2733】【HNOI 2012】永无乡 Splay启发式合并

    启发式合并而已啦,,

    调试时发现的错误点:insert后没有splay,把要拆开的树的点插入另一个树时没有把ch[2]和fa设为null,找第k大时没有先减k,,,

    都是常犯的错误,比赛时再这么粗心就得滚粗了

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define read(x) x=getint()
    using namespace std;
    inline int getint(){char c;int ret=0;for(c=getchar();c<'0'||c>'9';c=getchar());for(;c>='0'&&c<='9';c=getchar())ret=ret*10+c-'0';return ret;}
    struct node *null;
    struct node{
    	node();
    	node *fa,*ch[2];
    	int id,d,s;
    	bool pl() {return fa->ch[1]==this;}
    	void count() {s=ch[0]->s+ch[1]->s+1;}
    	void setc(node *r,bool c) {this->ch[c]=r; if (r!=null) r->fa=this;}
    }*rt[100003],pool[100003];
    node::node() {d=s=0;ch[0]=ch[1]=fa=null;}
    int tot=0,n,m;
    inline node *newnode(){
    	node *t=&pool[++tot];
    	t->ch[0]=t->ch[1]=t->fa=null;
    	return t;
    }
    inline void init() {null=&pool[0];null->s=null->d=0; null->ch[0]=null->ch[1]=null->fa=null;}
    inline void rotate(node *r){
    	node *f=r->fa; bool c=r->pl();
    	if (f->fa!=null) f->fa->setc(r,f->pl());
    	else r->fa=null;
    	f->setc(r->ch[!c],c); r->setc(f,!c);
    	f->count();
    }
    inline void splay(node *r){
    	for(;r->fa!=null;rotate(r))
    		if(r->fa->fa!=null)rotate(r->fa->pl()==r->pl()?r->fa:r);
    	r->count();
    }
    inline void ins(node *r,node *k){
    	int num=k->d; bool c;
    	while (r!=null){
    		if (num<r->d) c=0; else c=1;
    		if (r->ch[c]==null) {r->setc(k,c); splay(k); return;} else r=r->ch[c];
    	}
    }
    inline node *fdr(node *r) {while (r->fa!=null) r=r->fa; return r;}
    inline int QQ(node *r,int k){
    	if (r->s<k) return -1;
    	while (r!=null){
    		if (r->ch[0]->s>=k) r=r->ch[0];
    		else if (r->ch[0]->s+1>=k) return r->id;
    		else k-=r->ch[0]->s+1,r=r->ch[1];
    	}
    }
    inline void BB(node *r,node *t){
    	if (t==null) return;
    	BB(r,t->ch[0]); BB(r,t->ch[1]);
    	t->ch[0]=t->ch[1]=t->fa=null;
    	ins(r,t); splay(t);
    }
    int main(){
    	init();
    	read(n); read(m);
    	int x,y; char c; node *s,*t;
    	for(int i=1;i<=n;++i) {rt[i]=newnode(); read(rt[i]->d); rt[i]->s=1; rt[i]->id=i;}
    	for(int i=1;i<=m;++i) {
    		read(x); read(y);
    		if (x==0||y==0) continue;
    		s=fdr(rt[x]); t=fdr(rt[y]);
    		if (s==t) continue;
    		if (s->s<t->s) swap(s,t);
    		BB(s,t);
    	}
    	read(m);
    	while (m--){
    		c=getchar();
    		while ((c!='Q')&&(c!='B')) c=getchar();
    		read(x); read(y);
    		switch (c){
    			case 'Q':
    				printf("%d
    ",QQ(fdr(rt[x]),y));
    			break;
    			case 'B':
    				s=fdr(rt[x]); t=fdr(rt[y]);
    				if (s==t) continue;
    				if (s->s<t->s) swap(s,t);
    				if (s!=t) BB(s,t);
    			break;
    		}
    	}
    	return 0;
    }
    

    PS:最后一组数据有一行是0 0,特判掉这个错误数据就行啦

  • 相关阅读:
    C++访问WebService gSoap方式
    vc6
    POS 60域用法
    本次操作由于这台计算机的限制而被取消
    POS的一点杂笔
    QT5.5
    注册表常用快捷键
    WebBrowser与IE的关系,如何设置WebBrowser工作在IE9模式下?
    js中的prototype属性
    WPF入门教程系列二十——ListView示例(二)
  • 原文地址:https://www.cnblogs.com/abclzr/p/5284872.html
Copyright © 2011-2022 走看看