[XSY 1556] 股神小D LCT维护子树信息
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[XSY 1556] 股神小D LCT维护子树信息相关的知识,希望对你有一定的参考价值。
实现
1 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cctype> 6 #include <algorithm> 7 #include <vector> 8 using namespace std; 9 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 10 #define LL long long 11 inline int rd(void) { 12 int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1; 13 int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f; 14 } 15 16 const int N = 200005; 17 const int T = 400005; 18 19 int tot; 20 struct E { 21 int t, x, y, sign; 22 friend inline bool operator < (E A, E B) { return A.t != B.t ? A.t < B.t : A.sign < B.sign; } 23 }Edge[T]; 24 25 int n, pre[N]; vector<int> g[N]; 26 void Parent(int x) { 27 for (vector<int>::iterator it = g[x].begin(); it != g[x].end(); it++) 28 if (pre[x] != *it) { 29 pre[*it] = x; 30 Parent(*it); 31 } 32 } 33 34 #define LC (c[x][0]) 35 #define RC (c[x][1]) 36 int c[N][2], par[N], siz[N], out[N]; LL sum; 37 38 inline void Up(int x) { siz[x] = siz[LC] + siz[RC] + out[x] + 1; } 39 inline bool Root(int x) { return c[par[x]][0] != x && c[par[x]][1] != x; } 40 inline void Rot(int x) { 41 int y = par[x], z = par[y]; 42 int L = (c[y][1] == x), R = L^1; 43 44 if (!Root(y)) 45 c[z][c[z][1] == y] = x; 46 par[x] = z; 47 48 if (c[x][R] > 0) 49 par[c[x][R]] = y; 50 c[y][L] = c[x][R]; 51 52 c[x][R] = y, par[y] = x; 53 Up(y), Up(x); 54 } 55 inline void Splay(int x) { 56 for (; !Root(x); Rot(x)) { 57 int y = par[x], z = par[y]; 58 if (!Root(y)) { (c[y][0] == x) ^ (c[z][0] == y) ? Rot(x) : Rot(y); } 59 } 60 } 61 62 inline void Expose(int x) { 63 for (int t = 0; x > 0; t = x, x = par[x]) { 64 Splay(x); 65 out[x] += siz[RC]; 66 RC = t; 67 out[x] -= siz[RC]; 68 } 69 } 70 71 inline void Reorder(int &x, int &y) { if (pre[y] == x) swap(x, y); } 72 inline void Link(int x, int y) { 73 // 保证 x 和 y 都是 Splay 的根 74 Reorder(x, y); 75 par[x] = y; 76 out[y] += siz[x]; 77 siz[y] += siz[x]; 78 } 79 inline void Cut(int x, int y) { 80 Reorder(x, y); 81 Expose(x); 82 Splay(x); 83 siz[x] -= siz[LC]; 84 par[LC] = 0, LC = 0; 85 } 86 87 void Travel(int x) { 88 if (!x) return; 89 Travel(LC); 90 printf("%d ", x); 91 Travel(RC); 92 } 93 void Print(int x) { Travel(x), puts(""); } 94 95 int main(void) { 96 #ifndef ONLINE_JUDGE 97 freopen("D.in", "r", stdin); 98 #endif 99 100 n = rd(); 101 F(i, 1, n-1) { 102 int x = rd(), y = rd(), l = rd(), r = rd(); 103 g[x].push_back(y), g[y].push_back(x); 104 Edge[++tot] = (E){l, x, y, +1}, Edge[++tot] = (E){r+1, x, y, -1}; 105 } 106 sort(Edge+1, Edge+tot+1); 107 108 Parent(1); 109 110 F(i, 1, n) siz[i] = 1; 111 F(i, 1, tot) { 112 int x = Edge[i].x, y = Edge[i].y, sign = Edge[i].sign; 113 if (sign == +1) { 114 Expose(x); 115 Splay(x); 116 Expose(y); 117 Splay(y); 118 sum += 1LL * siz[x] * siz[y]; 119 Link(x, y); 120 } 121 else Cut(x, y); 122 } 123 printf("%lld\n", sum); 124 125 return 0; 126 }
以上是关于[XSY 1556] 股神小D LCT维护子树信息的主要内容,如果未能解决你的问题,请参考以下文章