洛谷P4211 LCA

题意:多次询问,每次求点的标号在[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代码

猜你喜欢

转载自www.cnblogs.com/huyufeifei/p/10356033.html