首页 > 代码库 > BZOJ3631 松鼠的新家(树链剖分)
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\n", query(p[i])); 113 else printf("%d\n", query(p[i]) - 1); 114 115 116 return 0; 117 118 }
BZOJ3631 松鼠的新家(树链剖分)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。