zoukankan      html  css  js  c++  java
  • HDU 5467

    第一次写LCT,各种模板加入。。。以后都只遇到有新意的题目再更新了

    这道题就是LCT,但是,难在一个回退的操作。这时,可以通过改变执行顺序,先把要回退后再做的操作先执行了,再回退到之前的执行。这时,建立一棵操作树,使用DFS可以回退的特点,就能完成这一功能。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #pragma comment(linker, "/STACK:1024000000,1024000000") 
    #define LL long long
    using namespace std;
    
    const int MAX=300050;
    const LL MOD=1e9+7;
    int fa[MAX],ch[MAX][2],son[MAX],nxt[MAX],rev[MAX];
    int n,q;
    int opt_x[MAX],opt_u[MAX],opt_v[MAX],opt_d[MAX];
    LL val[MAX],mul[MAX];
    LL ans[MAX];
    set<long long>st;
    int stack[MAX];
    
    void update(int x){
    	int l=ch[x][0],r=ch[x][1];
    	mul[x]=val[x];
    	if(l) mul[x]=mul[x]*mul[l]%MOD;
    	if(r) mul[x]=mul[x]*mul[r]%MOD;
    }
    
    void pushdown(int x){
         int l=ch[x][0],r=ch[x][1];
         if(rev[x]){
             rev[x]^=1;rev[l]^=1;rev[r]^=1;
             swap(ch[x][0],ch[x][1]);
         }
    }
    
    bool isroot(int x){
         return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
    }
    
    void rotate(int x){
         int y=fa[x],z=fa[y],l,r;
         if(ch[y][0]==x)l=0;else l=1;r=l^1;
         if(!isroot(y))
         {
             if(ch[z][0]==y)ch[z][0]=x;
             else ch[z][1]=x;
         }
         fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
         ch[y][l]=ch[x][r];ch[x][r]=y;
         update(y);update(x);
    }
    
    void splay(int u){
    	int top=0; stack[++top]=u;
    	for(int i=u;!isroot(i);i=fa[i]) stack[++top]=fa[i];
    	while(top) pushdown(stack[top--]);
    	while(!isroot(u)){
    		int y=fa[u],z=fa[y];
    		if(!isroot(y)){
                 if(ch[y][0]==u^ch[z][0]==y)rotate(u);
                 else rotate(y);
    		}
    		rotate(u);
    	}
    }
    
    bool connect(int u,int v){
    	while(fa[u]) u=fa[u];
    	while(fa[v]) v=fa[v];
    	return u==v;
    }
    
    void access(int u){
    	for(int t=0;u;t=u,u=fa[u]){
    		splay(u),ch[u][1]=t,update(u);
    	}
    }
    
    void makeroot(int x){
    	access(x),splay(x),rev[x]^=1;
    }
    
    bool link(int u,int v){
    	if(u>v) swap(u,v);
    	if(u==v) return false;
    	if(connect(u,v)) return false;
    	makeroot(u),fa[u]=v;
    	st.insert(MAX*u+v);
    	return true;
    }
    
    bool cut(int u,int v){
    	if(u>v) swap(u,v);
    	if(u==v) return false;
    	if(st.find(MAX*u+v)==st.end()) return false;
    	makeroot(u),access(v),splay(v);
    	fa[u]=0,ch[v][0]=0;
    	st.erase(MAX*u+v);
    	return true;
    }
    
    void dfs(int x){
    	bool done=false;
    	LL tmp;
    	int u=opt_u[x],v=opt_v[x];
    	if(opt_x[x]==1) done=link(u,v);
    	if(opt_x[x]==2) done=cut(u,v);
    	if(opt_x[x]==4){
    		if(u==v) ans[opt_d[x]]=val[u];
    		else{
    			if(connect(u,v)){
    				makeroot(u);
    				access(v),splay(v);
    				ans[opt_d[x]]=mul[v];
    			}
    			else{
    				ans[opt_d[x]]=0;
    			}
    		}
    	}
    	if(opt_x[x]==5){
    		done=true;
    		splay(u);
    		tmp=val[u];
    		val[u]=v*(v-1)/2%MOD;
    		update(u);
    	}
    	for(int i=son[x];i;i=nxt[i]) dfs(i);
    	if(done){
    		if(opt_x[x]==1) done=cut(u,v);
    		if(opt_x[x]==2) done=link(u,v);
    		if(opt_x[x]==5){
    			splay(u);
    			val[u]=tmp;
    			update(u);
    		}
    	}
    }
    
    int main(){
    	int T;
    	LL k;
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d",&n,&q);
    		for(int i=1;i<=n;i++){
    			scanf("%lld",&k);
    			val[i]=mul[i]=k*(k-1)/2%MOD;
    		}
    		for(int i=0;i<=n+10;i++) rev[i]=0,fa[i]=0,ch[i][0]=ch[i][1]=0;
    		for(int i=0;i<=q+10;i++) nxt[i]=son[i]=0;
    		st.clear();
    		int tot=0;
    		for(int i=1;i<=q;i++){
    			scanf("%d",&opt_x[i]);
    			if(opt_x[i]==3){
    				scanf("%d",&opt_u[i]);
    				nxt[i]=son[opt_u[i]],son[opt_u[i]]=i;
    			}
    			else{
    				scanf("%d%d",&opt_u[i],&opt_v[i]);
    				nxt[i]=son[i-1],son[i-1]=i;
    				if(opt_x[i]==4){
    					opt_d[i]=++tot;
    				}
    			}
    		}
    		dfs(0);
    		for(int i=1;i<=tot;i++){
    			printf("%lld
    ",ans[i]);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    一次http请求的过程
    log4j每天生成一个文件配置
    解决eclipse中maven多模块项目显示不全的问题
    docker上启动nginx,并配置修改nginx的配置文件
    springboot项目打成jar包后台运行在linux上
    《写给大家看的设计书》粗读整理
    一些需要改进的点
    b端产品的疑问
    产品经理小白初起步
    用visualvm观察远程服务器java项目的两种办法
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4854976.html
Copyright © 2011-2022 走看看