bzoj4196 [Noi2015]软件包管理器 树链剖分
Posted iat14
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4196 [Noi2015]软件包管理器 树链剖分相关的知识,希望对你有一定的参考价值。
需要按照DFS来init,不能用BFS。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 const int MAXN = 200005,MAXM = 200005; 7 int cnt,tot,n,m; 8 int head[MAXN],fa[MAXN],que[MAXN],dep[MAXN],son[MAXN],top[MAXN],pos[MAXN],idx[MAXN],siz[MAXN],rgt[MAXN]; 9 int to[MAXM],nxt[MAXM]; 10 int lzy[4 * MAXN],data[4 * MAXN]; 11 void add(int x,int y) 12 { 13 nxt[++cnt] = head[x]; 14 to[cnt] = y; 15 head[x] = cnt; 16 } 17 int dfs1(int x) 18 { 19 idx[pos[x] = ++tot] = x; 20 rgt[x] = tot; 21 for (int i = head[x];i;i = nxt[i]) 22 { 23 if (to[i] == fa[x]) continue; 24 if (to[i] != son[x]) continue; 25 top[to[i]] = top[x]; 26 rgt[x] = max(rgt[x],dfs1(to[i])); 27 } 28 for (int i = head[x];i;i = nxt[i]) 29 { 30 if (to[i] == fa[x]) continue; 31 if (to[i] == son[x]) continue; 32 top[to[i]] = to[i]; 33 rgt[x] = max(rgt[x],dfs1(to[i])); 34 } 35 return rgt[x]; 36 } 37 void build(int k,int l,int r) 38 { 39 lzy[k] = -1; 40 if (l == r) return; 41 int mid = l + r >> 1; 42 build(k << 1,l,mid); 43 build(k << 1 | 1,mid + 1,r); 44 } 45 void init() 46 { 47 int top = 0; 48 que[++top] = 1; 49 dep[1] = 1; 50 for (int i = top;i <= top;i++) 51 { 52 int u = que[i]; 53 // printf("bfs %d ",u); 54 siz[u] = 1; 55 for (int o = head[u];o;o = nxt[o]) 56 { 57 if (to[o] == fa[u]) continue; 58 dep[to[o]] = dep[u] + 1; 59 que[++top] = to[o]; 60 } 61 } 62 for (int i = top;i;i--) 63 { 64 int u = que[i]; 65 siz[fa[u]] += siz[u]; 66 if (siz[u] > siz[son[fa[u]]]) 67 { 68 son[fa[u]] = u; 69 } 70 } 71 ::top[1] = 1; 72 dfs1(1); 73 build(1,1,tot); 74 } 75 void push_down(int k,int l,int r) 76 { 77 if (lzy[k] < 0) return; 78 int ch1 = k << 1,ch2 = k << 1 | 1,mid = l + r >> 1; 79 lzy[ch1] = lzy[ch2] = lzy[k]; 80 data[ch1] = (mid - l + 1) * lzy[k]; 81 data[ch2] = (r - mid) * lzy[k]; 82 lzy[k] = -1; 83 } 84 int vec_query(int k,int l,int r,int x,int y,int o) 85 { 86 if (x <= l && r <= y) 87 { 88 if (o == 0) return (r - l + 1) - data[k]; 89 return data[k]; 90 } 91 push_down(k,l,r); 92 int mid = l + r >> 1,res = 0; 93 if (x <= mid) res += vec_query(k << 1,l,mid,x,y,o); 94 if (y > mid) res += vec_query(k << 1 | 1,mid + 1,r,x,y,o); 95 return res; 96 } 97 void vec_change(int k,int l,int r,int x,int y,int o) 98 { 99 if (x <= l && r <= y) 100 { 101 if (o == 0) 102 { 103 data[k] = 0; 104 lzy[k] = 0; 105 return; 106 } 107 data[k] = (r - l + 1); 108 lzy[k] = 1; 109 return; 110 } 111 push_down(k,l,r); 112 int mid = l + r >> 1; 113 if (x <= mid) vec_change(k << 1,l,mid,x,y,o); 114 if (y > mid) vec_change(k << 1 | 1,mid + 1,r,x,y,o); 115 data[k] = data[k << 1] + data[k << 1 | 1]; 116 } 117 int tree_query(int l,int r,int o) 118 { 119 int res = 0; 120 while (top[l] != top[r]) 121 { 122 if (dep[top[l]] < dep[top[r]]) swap(l,r); 123 res += vec_query(1,1,tot,pos[top[l]],pos[l],o); 124 l = fa[top[l]]; 125 } 126 if (dep[l] < dep[r]) swap(l,r); 127 res += vec_query(1,1,tot,pos[r],pos[l],o); 128 return res; 129 } 130 void tree_change(int l,int r,int o) 131 { 132 int res = 0; 133 while (top[l] != top[r]) 134 { 135 if (dep[top[l]] < dep[top[r]]) swap(l,r); 136 vec_change(1,1,tot,pos[top[l]],pos[l],o); 137 l = fa[top[l]]; 138 } 139 if (dep[l] < dep[r]) swap(l,r); 140 vec_change(1,1,tot,pos[r],pos[l],o); 141 } 142 int area_query(int k,int o) 143 { 144 return vec_query(1,1,tot,pos[k],rgt[k],o); 145 } 146 void area_change(int k,int o) 147 { 148 vec_change(1,1,tot,pos[k],rgt[k],o); 149 } 150 int main() 151 { 152 scanf("%d",&n); 153 for (int i = 2;i <= n;i++) 154 { 155 scanf("%d",&fa[i]); 156 fa[i]++; 157 add(fa[i],i); 158 } 159 init(); 160 // for (int i = 1;i <= tot;i++) printf("%d ^%d ",i,idx[i]); 161 // for (int i = 1;i <= tot;i++) printf("%d *%d ",i,rgt[i]); 162 // for (int i = 1;i <= tot;i++) printf("%d *%d ",i,son[i]); 163 // for (int i = 1;i <= tot;i++) printf("%d &%d ",i,top[i]); 164 // for (int i = 2;i <= tot;i++) printf("%d $%d ",i,siz[i]); 165 scanf("%d",&m); 166 for (int i = 1;i <= m;i++) 167 { 168 char s[20]; 169 int opt; 170 scanf("%s%d",s,&opt); 171 opt++; 172 if (s[0] == ‘i‘) 173 { 174 printf("%d ",tree_query(1,opt,0)); 175 tree_change(1,opt,1); 176 }else 177 { 178 printf("%d ",area_query(opt,1)); 179 area_change(opt,0); 180 } 181 } 182 return 0; 183 }
以上是关于bzoj4196 [Noi2015]软件包管理器 树链剖分的主要内容,如果未能解决你的问题,请参考以下文章
Bzoj 4196: [Noi2015]软件包管理器 树链剖分
[UOJ#128][BZOJ4196][Noi2015]软件包管理器