BZOJ3631 松鼠的新家(树链剖分)

题目链接 松鼠的新家 

差不多可以说是树链剖分的模板题了,直接维护即可。

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 #define REP(i,n)                for(int i(0); i <  (n); ++i)
  6 #define rep(i,a,b)              for(int i(a); i <= (b); ++i)
  7 #define dec(i,a,b)              for(int i(a); i >= (b); --i)
  8 #define for_edge(i,x)           for(int i = H[x]; i; i = X[i])
  9 
 10 #define LL      long long
 11 #define ULL     unsigned long long
 12 #define MP      make_pair
 13 #define PB      push_back
 14 #define FI      first
 15 #define SE      second
 16 #define INF     1 << 30
 17 
 18 
 19 const int N     =    300000      +       10;
 20 const int M     =    10000       +       10;
 21 const int Q     =    1000        +       10;
 22 const int A     =    30          +       1;
 23 
 24 int E[N << 1], H[N << 1], X[N << 1];
 25 int c[N];
 26 int top[N];
 27 int fa[N];
 28 int deep[N];
 29 int num[N];
 30 int son[N];
 31 int fp[N];
 32 int p[N];
 33 int et, pos;
 34 int a[N];
 35 int n, x, y;
 36 
 37 inline int lowbit(int x){ return (x) & (-x);}
 38 
 39 inline int query(int x){int ret = 0; for (; x; x -= lowbit(x)) ret += c[x]; return ret;}
 40 inline void add(int x, int val){ for (; x <= n; x += lowbit(x)) c[x] += val;}
 41 
 42 inline void addedge(int a, int b){
 43     E[++et] = b, X[et] = H[a], H[a] = et;
 44     E[++et] = a, X[et] = H[b], H[b] = et;
 45 }
 46 
 47 void dfs(int x, int pre){
 48     deep[x] = deep[pre] + 1;
 49     fa[x] = pre;
 50     num[x] = 1;
 51     for_edge(i, x){
 52         int v = E[i];
 53         if (v != pre){
 54             dfs(v, x);
 55             num[x] += num[v];
 56             if (son[x] != -1 || num[v] > num[son[x]])
 57                 son[x] = v;
 58         }
 59     }
 60 }
 61 
 62 void getpos(int x, int sp){
 63     top[x] = sp;
 64     p[x] = ++pos;
 65     fp[p[x]] = x;
 66     if (son[x] == -1) return;
 67     getpos(son[x], sp);
 68     for_edge(i, x){
 69         int v = E[i];
 70         if (v != son[x] && v != fa[x]) 
 71             getpos(v, v);
 72     }
 73 }
 74 
 75 void cover(int u, int v, int val){
 76     int f1 = top[u], f2 = top[v];
 77     int tmp = 0;
 78     while (f1 != f2){
 79         if (deep[f1] < deep[f2]){
 80             swap(f1, f2);
 81             swap(u, v);
 82         }
 83         add(p[f1], val);
 84         add(p[u] + 1, -val);
 85         u = fa[f1];
 86         f1 = top[u];
 87     }
 88 
 89     if (deep[u] > deep[v]) swap(u, v);
 90     add(p[u], val);
 91     add(p[v] + 1, -val);
 92 }
 93 
 94 int main(){
 95 
 96     scanf("%d", &n);
 97     rep(i, 1, n) scanf("%d", a + i);
 98     rep(i, 1, n - 1){
 99         scanf("%d%d", &x, &y);
100         addedge(x, y);
101     }
102     
103 
104     memset(son, -1, sizeof son);
105     dfs(1, 0);
106     getpos(1, 1);    
107     rep(i, 1, n - 1){
108         x = a[i], y = a[i + 1];
109         cover(x, y, 1);
110     }
111 
112     rep(i, 1, n) if (i == a[1]) printf("%d
", query(p[i]));
113     else printf("%d
", query(p[i]) - 1);
114     
115 
116     return 0;
117 
118 }
原文地址:https://www.cnblogs.com/cxhscst2/p/6352262.html