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

股神小D [点分治 or LCT]

股神小L [贪心]

2016vijos 1-2 股神小L(堆)

[xsy2913]enos

LCT维护子树信息

股神小L 2016Vijos省选集训 day1