• 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;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    云南9日游攻略
    移动端和边缘端的深度学习概述
    卷积、反卷积与膨胀卷积
    语义分割简述
    数据结构与算法----2总览
    python 中easydict库解析json文件
    python命令行传参解析(二)------ConfigParser
    plt.imshow与cv2.imshow显示颜色问题
    图卷积GCN
    十、mysql 数据类型
  • 原文地址:https://www.cnblogs.com/zzyer/p/8454313.html
Copyright © 2020-2023  润新知