zoukankan      html  css  js  c++  java
  • [BJOI2014]大融合

    题目描述

    小强要在NN 个孤立的星球上建立起一套通信系统。这套通信系统就是连接NN 个点的一个树。 这个树的边是一条一条添加上去的。在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它的简单路径的数量。

    现在,你的任务就是随着边的添加,动态的回答小强对于某些边的负载的 询问。

    输入输出格式

    输入格式:

    第一行包含两个整数 N, Q ,表示星球的数量和操作的数量。星球从 1 开始编号。

    接下来的 Q 行,每行是如下两种格式之一:

    • A x y 表示在 x 和 y 之间连一条边。保证之前 x 和 y 是不联通的。
    • Q x y表示询问 (x,y) 这条边上的负载。保证 x 和 y 之间有一条边。

    输出格式:

    对每个查询操作,输出被查询的边的负载。

    输入输出样例

    输入样例#1: 
    8 6
    A 2 3
    A 3 4
    A 3 8
    A 8 7
    A 6 5
    Q 3 8
    输出样例#1: 
    6

    说明

    对于所有数据,1≤N,Q≤1000000

    玄学LCT。。。。

    首先根据我的常识一般的LCT是不能维护子树的,,,如果要的话好像得用一个叫top_tree的玩意。。。

    但这个题需要维护的子树信息太简单了所以可以直接用LCT维护子树。

    具体的说,子树有实有虚,一般的LCT只能维护实子树的信息(也就是重链)。

    对于本题来说,我们多加一个数组son[x]表示x的虚子树的siz和。

    然后发现只有树中的轻重边变化或者树的形态变化的时候才会影响到siz和son。

    例如ACCESS,LINK,CUT。

    讨论一下就好了。

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 1000005
    using namespace std;
    struct LCT{
    	int f[maxn],ch[maxn][2];
    	int siz[maxn],son[maxn];
    	int tag[maxn],q[maxn],tp;
    	int n,m,uu,vv;
    	char cr;
    	
    	inline int get(int x){
    		return ch[f[x]][1]==x;
    	}
    	
    	inline bool isroot(int x){
    		return (ch[f[x]][0]!=x&&ch[f[x]][1]!=x);
    	}
    	
    	inline void pushdown(int x){
    		if(tag[x]){
    			tag[x]=0,swap(ch[x][0],ch[x][1]);
    			tag[ch[x][0]]^=1,tag[ch[x][1]]^=1;
    		}
    	}
    	
    	inline void update(int x){
    		siz[x]=1+siz[ch[x][0]]+siz[ch[x][1]]+son[x];
    	}
    	
    	inline void rotate(int x){
    		int fa=f[x],ffa=f[fa],tp=get(x);
    		ch[fa][tp]=ch[x][tp^1],f[ch[fa][tp]]=fa;
    		ch[x][tp^1]=fa,f[fa]=x;
    		f[x]=ffa;
    		if(ch[ffa][1]==fa||ch[ffa][0]==fa) ch[ffa][ch[ffa][1]==fa]=x;
    		update(fa),update(x);
    	}
    	
    	inline void splay(int x){
    		tp=0;
    		for(int i=x;;i=f[i]){
    			q[++tp]=i;
    			if(isroot(i)) break;
    		}
    		
    		for(;tp;tp--) pushdown(q[tp]);
    		
    		for(;!isroot(x);rotate(x))
    		    if(!isroot(f[x])) rotate(get(f[x])==get(x)?f[x]:x);
    	}
    	
    	inline void access(int x){
    		for(int t=0;x;t=x,x=f[x]){
    			splay(x);
    			son[x]+=siz[ch[x][1]]-siz[t];
    			ch[x][1]=t,update(x);
    		}
    	}
    	
    	inline void makeroot(int x){
    		access(x),splay(x);
    		tag[x]^=1;
    	}
    	
    	inline void link(int x,int y){
    		makeroot(x),access(y),splay(y);
    		f[x]=y,son[y]+=siz[x],update(y);
    	}
    	
    	inline void solve(){
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<=n;i++) siz[i]=1;
    		
    		while(m--){
    			cr=getchar();
    			while(cr!='A'&&cr!='Q') cr=getchar();
    			scanf("%d%d",&uu,&vv);
    			if(cr=='A') link(uu,vv);
    			else{
    				makeroot(uu);
    				access(vv),splay(vv);
    				printf("%lld
    ",(ll)(siz[uu])*(ll)(siz[vv]-siz[uu]));
    			}
    		}
    	}
    }mine;
    
    int main(){
    	mine.solve();
    	return 0;
    }
    

      

  • 相关阅读:
    idea报“Usage of API documented as @since 1.7”这一问题的解决方法
    分页的总页数算法
    Error evaluating expression 'category.id != null and category.id != '''. Cause: org.apache.ibatis.og
    json日期处理类
    解决maven过滤必需配置文件的方法
    数据库配置文件
    springmvc 提供的统一解决json中文乱码配置
    EXPLAIN 命令详解
    MySQL索引与Index Condition Pushdown(二)
    【MySQL】性能优化之 Index Condition Pushdown
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8425236.html
Copyright © 2011-2022 走看看