1. 程式人生 > >洛谷P4211 LCA

洛谷P4211 LCA

col return %d .... 喜歡 min add struct hide

題意:多次詢問,每次求點的標號在[l, r]之間的所有點到點z的lca的深度。

解:看到這題有沒有想到某一道很熟悉的題?紫妹和幽香是17歲的少女,喜歡可愛的東西......

顯然這就是開店的超級無敵弱化版......直接套用做法就行了。

記得對"愛你一生一世"取模。(滑稽)

技術分享圖片
  1 #include <cstdio>
  2 #include <algorithm>
  3 
  4 typedef long long LL;
  5 const int N = 50010, M = 5000010;
  6 
  7 struct Edge {
  8     int nex, v;
9 }edge[N]; int tp; 10 11 int e[N], top[N], num, fa[N], siz[N], son[N], d[N], n, pos[N]; 12 LL sum[M]; 13 int rt[N], tot, ls[M], rs[M], tag[M]; 14 15 inline void adde(int x, int y) { 16 tp++; 17 edge[tp].v = y; 18 edge[tp].nex = e[x]; 19 e[x] = tp; 20 return; 21 } 22
23 void DFS1(int x) { // get siz fa son d 24 siz[x] = 1; 25 d[x] = d[fa[x]] + 1; 26 for(int i = e[x]; i; i = edge[i].nex) { 27 int y = edge[i].v; 28 fa[y] = x; 29 DFS1(y); 30 siz[x] += siz[y]; 31 if(siz[y] > siz[son[x]]) { 32 son[x] = y;
33 } 34 } 35 return; 36 } 37 38 void DFS2(int x, int f) { // get pos id top 39 top[x] = f; 40 pos[x] = ++num; 41 if(son[x]) { 42 DFS2(son[x], f); 43 } 44 for(int i = e[x]; i; i = edge[i].nex) { 45 int y = edge[i].v; 46 if(y == son[x]) { 47 continue; 48 } 49 DFS2(y, y); 50 } 51 return; 52 } 53 54 void add(int x, int &y, int L, int R, int l, int r) { 55 if(!y || x == y) { 56 y = ++tot; 57 sum[y] = sum[x]; 58 tag[y] = tag[x]; 59 ls[y] = ls[x]; 60 rs[y] = rs[x]; 61 } 62 sum[y] += std::min(R, r) - std::max(L, l) + 1; 63 if(L <= l && r <= R) { 64 tag[y]++; 65 return; 66 } 67 int mid = (l + r) >> 1; 68 if(L <= mid) { 69 add(ls[x], ls[y], L, R, l, mid); 70 } 71 if(mid < R) { 72 add(rs[x], rs[y], L, R, mid + 1, r); 73 } 74 return; 75 } 76 77 LL ask(int x, int y, int L, int R, int l, int r, int vx, int vy) { 78 if(L <= l && r <= R) { 79 return sum[y] - sum[x] + 1ll * (vy - vx) * (r - l + 1); 80 } 81 vx += tag[x]; 82 vy += tag[y]; 83 int mid = (l + r) >> 1; 84 LL ans = 0; 85 if(L <= mid) { 86 ans += ask(ls[x], ls[y], L, R, l, mid, vx, vy); 87 } 88 if(mid < R) { 89 ans += ask(rs[x], rs[y], L, R, mid + 1, r, vx, vy); 90 } 91 return ans; 92 } 93 94 inline void add(int x, int time) { 95 while(x) { 96 add(rt[time - 1], rt[time], pos[top[x]], pos[x], 1, n); 97 x = fa[top[x]]; 98 } 99 return; 100 } 101 102 inline LL ask(int x, int y, int z) { 103 LL ans = 0; 104 while(z) { 105 ans += ask(rt[x - 1], rt[y], pos[top[z]], pos[z], 1, n, 0, 0); 106 z = fa[top[z]]; 107 } 108 return ans; 109 } 110 111 int main() { 112 int q; 113 scanf("%d%d", &n, &q); 114 for(int i = 2, x; i <= n; i++) { 115 scanf("%d", &x); 116 adde(x + 1, i); 117 } 118 DFS1(1); 119 DFS2(1, 1); 120 for(int i = 1; i <= n; i++) { 121 add(i, i); 122 } 123 for(int i = 1, x, y, z; i <= q; i++) { 124 scanf("%d%d%d", &x, &y, &z); 125 LL t = ask(x + 1, y + 1, z + 1); 126 printf("%lld\n", t % 201314); 127 } 128 return 0; 129 }
AC代碼

洛谷P4211 LCA