Luogu4219 BJOI2014 大融合 LCT

Posted itst

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu4219 BJOI2014 大融合 LCT相关的知识,希望对你有一定的参考价值。

传送门

题意:写一个数据结构,支持图上连边(保证图是森林)和询问一条边两端的连通块大小的乘积。$ ext{点数、询问数} leq 10^5$


图上连边,$LCT$跑不掉

支持子树$size$有点麻烦。我们需要虚子树的$size$和(实子树的可以直接$pushup$),那么我们对于每一个点就去维护其虚子树的$size$和,那么每一个点的子树和就是可以维护的了。可以知道只有$link$和$access$操作会修改虚子树和(其他都在实链上进行操作),稍微加一点东西就行了。相对来说还是比较裸。

注意$pushup$的改变。

  1 #include<bits/stdc++.h>
  2 //This code is written by Itst
  3 using namespace std;
  4 
  5 inline int read(){
  6     int a = 0;
  7     bool f = 0;
  8     char c = getchar();
  9     while(c != EOF && !isdigit(c)){
 10         if(c == -)
 11             f = 1;
 12         c = getchar();
 13     }
 14     while(c != EOF && isdigit(c)){
 15         a = (a << 3) + (a << 1) + (c ^ 0);
 16         c = getchar();
 17     }
 18     return f ? -a : a;
 19 }
 20 
 21 const int MAXN = 100010;
 22 struct node{
 23     int size , ch[2] , fa , allSize;
 24     bool mark;
 25 }Tree[MAXN];
 26 int N , M;
 27 
 28 inline bool nroot(int x){
 29     return Tree[Tree[x].fa].ch[0] == x || Tree[Tree[x].fa].ch[1] == x;
 30 }
 31 
 32 inline bool son(int x){
 33     return Tree[Tree[x].fa].ch[1] == x;
 34 }
 35 
 36 inline void pushup(int x){
 37     Tree[x].allSize = Tree[Tree[x].ch[0]].allSize + Tree[Tree[x].ch[1]].allSize + Tree[x].size + 1;
 38 }
 39 
 40 inline void ZigZag(int x){
 41     bool f = son(x);
 42     int y = Tree[x].fa , z = Tree[y].fa , w = Tree[x].ch[f ^ 1];
 43     if(nroot(y))
 44         Tree[z].ch[son(y)] = x;
 45     Tree[x].fa = z;
 46     Tree[x].ch[f ^ 1] = y;
 47     Tree[y].fa = x;
 48     Tree[y].ch[f] = w;
 49     if(w)
 50         Tree[w].fa = y;
 51     pushup(y);
 52     pushup(x);
 53 }
 54 
 55 inline void pushdown(int x){
 56     if(Tree[x].mark){
 57         Tree[Tree[x].ch[0]].mark ^= 1;
 58         Tree[Tree[x].ch[1]].mark ^= 1;
 59         Tree[x].mark = 0;
 60         swap(Tree[x].ch[0] , Tree[x].ch[1]);
 61     }
 62 }
 63 
 64 void pushdown_all(int x){
 65     if(nroot(x))
 66         pushdown_all(Tree[x].fa);
 67     pushdown(x);
 68 }
 69 
 70 inline void Splay(int x){
 71     pushdown_all(x);
 72     while(nroot(x)){
 73         if(nroot(Tree[x].fa))
 74             ZigZag(son(x) == son(Tree[x].fa) ? Tree[x].fa : x);
 75         ZigZag(x);
 76     }
 77 }
 78 
 79 inline void access(int x){
 80     for(int y = 0 ; x ; y = x , x = Tree[x].fa){
 81         Splay(x);
 82         Tree[x].size = Tree[x].size + Tree[Tree[x].ch[1]].allSize - Tree[y].allSize;
 83         Tree[x].ch[1] = y;
 84         pushup(x);
 85     }
 86 }
 87 
 88 inline void makeroot(int x){
 89     access(x);
 90     Splay(x);
 91     Tree[x].mark ^= 1;
 92 }
 93 
 94 inline void split(int x , int y){
 95     makeroot(x);
 96     access(y);
 97     Splay(y);
 98 }
 99 
100 inline void link(int x , int y){
101     split(x , y);
102     Tree[x].fa = y;
103     Tree[y].size += Tree[x].allSize;
104     pushup(y);
105 }
106 
107 inline char getc(){
108     char c = getchar();
109     while(!isupper(c))
110         c = getchar();
111     return c;
112 }
113 
114 int main(){
115 #ifndef ONLINE_JUDGE
116     freopen("4219.in" , "r" , stdin);
117     //freopen("4219.out" , "w" , stdout);
118 #endif
119     N = read();
120     for(int i = 1 ; i <= N ; ++i)
121         Tree[i].allSize = 1;
122     for(M = read() ; M ; --M)
123         if(getc() == A)
124             link(read() , read());
125         else{
126             int a = read() , b = read();
127             split(a , b);
128             printf("%lld
" , 1ll * Tree[a].allSize * (Tree[b].allSize - Tree[a].allSize));
129         }
130     return 0;
131 }

 

以上是关于Luogu4219 BJOI2014 大融合 LCT的主要内容,如果未能解决你的问题,请参考以下文章

P4219 [BJOI2014]大融合(LCT)

P4219 [BJOI2014]大融合

洛谷P4219 - [BJOI2014]大融合

LuoguP4219 [BJOI2014]大融合(LCT)

洛谷P4219 [BJOI2014]大融合(LCT,Splay)

bzoj4530:[Bjoi2014]大融合