zoukankan      html  css  js  c++  java
  • BZOJ 4551 [Tjoi2016&Heoi2016]树

    题解:动态树,维护Splay最深的被标记过的点

    每个询问先Access(x);

    当然用树链剖分也可以

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int maxn=100009;
    const int oo=1000000000;
    
    int n,T;
    
    int fa[maxn],ch[maxn][2],dest[maxn],v[maxn];
    inline int son(int x){
    	if(ch[fa[x]][1]==x)return 1;
    	else return 0;
    }
    inline void pushup(int x){
    	dest[x]=dest[ch[x][1]];
    	if(!dest[x]){
    		if(v[x])dest[x]=x;
    	}
    	if(!dest[x])dest[x]=dest[ch[x][0]];
    }
    inline bool isroot(int x){
    	return (ch[fa[x]][0]!=x)&&(ch[fa[x]][1]!=x);
    }
    
    inline void Rotate(int x){
    	int y=fa[x];
    	int z=fa[y];
    	int b=son(x),c=son(y);
    	int a=ch[x][b^1];
    	if(!isroot(y))ch[z][c]=x;
    	fa[x]=z;
    	if(a)fa[a]=y;
    	ch[y][b]=a;
    	fa[y]=x;ch[x][b^1]=y;
    	pushup(y);pushup(x);
    }
    void Splay(int x){
    	while(!isroot(x)){
    		int y=fa[x];
    		if(isroot(y)){
    			Rotate(x);
    		}else{
    			if(son(x)==son(y)){
    				Rotate(y);Rotate(x);
    			}else{
    				Rotate(x);Rotate(x);
    			}
    		}
    	}
    }
    
    void Access(int x){
    	for(int t=0;x;t=x,x=fa[x]){
    		Splay(x);ch[x][1]=t;pushup(x);
    	}
    }
    
    
    int cntedge;
    int head[maxn];
    int to[maxn<<1],nex[maxn<<1];
    void Addedge(int x,int y){
    	 nex[++cntedge]=head[x];
    	 to[cntedge]=y;
    	 head[x]=cntedge;
    }
    
    queue<int>q;
    int father[maxn];
    void Bfs(){
    	q.push(1);
    	while(!q.empty()){
    		int x=q.front();q.pop();
    		for(int i=head[x];i;i=nex[i]){
    			if(to[i]==father[x])continue;
    			father[to[i]]=x;
    			fa[to[i]]=x;
    			q.push(to[i]);
    		}
    	}
    }
    
    int main(){
    	scanf("%d%d",&n,&T);
    	for(int i=1;i<=n-1;++i){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		Addedge(x,y);
    		Addedge(y,x);
    	}
    	
    	v[1]=1;dest[1]=1;
    	Bfs();
    	while(T--){
    		char opty[10];
    		scanf("%s",opty);
    		int x;
    		scanf("%d",&x);
    		if(opty[0]=='C'){
    			Splay(x);v[x]=1;pushup(x);
    		}else{
    			Access(x);Splay(x);printf("%d
    ",dest[x]);
    		}
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    java使用io流读取windows文件乱码问题
    java的io字符流关闭和刷新.flush();
    java使用io流实现图片复制
    java8新特性-函数式接口详细讲解及案例
    java8的lambda过滤list遍历集合,排序
    java复制对象,复制对象属性,只可复制两个对象想同的属性名。也可自定义只复制需要的属性。
    详讲KMP算法
    java栈和队列
    请求中文乱码解决
    idea创建servlet步骤
  • 原文地址:https://www.cnblogs.com/zzyer/p/8454313.html
Copyright © 2011-2022 走看看