zoukankan      html  css  js  c++  java
  • 【刷题】BZOJ 4530 [Bjoi2014]大融合

    Description

    小强要在N个孤立的星球上建立起一套通信系统。这套通信系统就是连接N个点的一个树。

    这个树的边是一条一条添加上去的。在某个时刻,一条边的负载就是它所在的当前能够

    联通的树上路过它的简单路径的数量。

    例如,在上图中,现在一共有了5条边。其中,(3,8)这条边的负载是6,因

    为有六条简单路径2-3-8,2-3-8-7,3-8,3-8-7,4-3-8,4-3-8-7路过了(3,8)。

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

    询问。

    Input

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

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

    A x y 表示在x和y之间连一条边。保证之前x和y是不联通的。

    Q x y 表示询问(x,y)这条边上的负载。保证x和y之间有一条边。

    1≤N,Q≤100000

    Output

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

    Sample Input

    8 6  
    A 2 3  
    A 3 4  
    A 3 8  
    A 8 7  
    A 6 5  
    Q 3 8
    

    Sample Output

    6
    

    Solution

    LCT的特殊操作——维护子树信息

    开个额外的Isize,记录节点虚子树的信息和

    然后就裸的题目了

    #include<bits/stdc++.h>
    #define ll long long
    #define db double
    #define ld long double
    const int MAXN=100000+10;
    int n,q;
    #define lc(x) ch[(x)][0]
    #define rc(x) ch[(x)][1]
    struct LCT{
    	int ch[MAXN][2],fa[MAXN],rev[MAXN],size[MAXN],Isize[MAXN],stack[MAXN],cnt;
    	inline bool nroot(int x)
    	{
    		return lc(fa[x])==x||rc(fa[x])==x;
    	}
    	inline void reverse(int x)
    	{
    		std::swap(lc(x),rc(x));
    		rev[x]^=1;
    	}
    	inline void pushup(int x)
    	{
    		size[x]=size[lc(x)]+size[rc(x)]+Isize[x]+1;
    	}
    	inline void pushdown(int x)
    	{
    		if(rev[x])
    		{
    			if(lc(x))reverse(lc(x));
    			if(rc(x))reverse(rc(x));
    			rev[x]=0;
    		}
    	}
    	inline void rotate(int x)
    	{
    		int f=fa[x],p=fa[f],c=(rc(f)==x);
    		if(nroot(f))ch[p][rc(p)==f]=x;
    		fa[ch[f][c]=ch[x][c^1]]=f;
    		fa[ch[x][c^1]=f]=x;
    		fa[x]=p;
    		pushup(f);
    		pushup(x);
    	}
    	inline void splay(int x)
    	{
    		cnt=0;
    		stack[++cnt]=x;
    		for(register int i=x;nroot(i);i=fa[i])stack[++cnt]=fa[i];
    		while(cnt)pushdown(stack[cnt--]);
    		for(register int y=fa[x];nroot(x);rotate(x),y=fa[x])
    			if(nroot(y))rotate((lc(y)==x)==(lc(fa[y])==y)?y:x);
    		pushup(x);
    	}
    	inline void access(int x)
    	{
    		for(register int y=0;x;x=fa[y=x])
    		{
    			splay(x);
    			Isize[x]+=size[rc(x)];
    			rc(x)=y;
    			Isize[x]-=size[rc(x)];
    			pushup(x);
    		}
    	}
    	inline void makeroot(int x)
    	{
    		access(x);splay(x);reverse(x);
    	}
    	inline void split(int x,int y)
    	{
    		makeroot(x);access(y);splay(y);
    	}
    	inline void link(int x,int y)
    	{
    		makeroot(x);access(y);splay(y);
    		fa[x]=y;
    		Isize[y]+=size[x];
    		pushup(y);
    	}
    };
    LCT T;
    #undef lc
    #undef rc
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char c='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(c!='')putchar(c);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    int main()
    {
    	read(n);read(q);
    	while(q--)
    	{
    		char opt[1];int x,y;
    		scanf("%s",opt);read(x);read(y);
    		if(opt[0]=='A')T.link(x,y);
    		if(opt[0]=='Q')
    		{
    			T.split(x,y);
    			write(1ll*(T.size[y]-T.size[x])*T.size[x],'
    ');
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    nginx预防常见攻击
    nginx性能优化(针对于高并发量仅供参考,并不是方案)
    nginx平滑升级(1.14--1.15)
    LAMP动静分离安装(源码安装)
    洛谷-P1098 字符串的展开
    洛谷-P1086 花生采摘
    洛谷-P1042 乒乓球
    洛谷-P1031 均分纸牌
    洛谷-P1023 税收与补贴问题
    洛谷-P1125 笨小猴
  • 原文地址:https://www.cnblogs.com/hongyj/p/8721935.html
Copyright © 2011-2022 走看看