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的主要内容,如果未能解决你的问题,请参考以下文章