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]软件包管理器 树链剖分

bzoj4196: [Noi2015]软件包管理器

[UOJ#128][BZOJ4196][Noi2015]软件包管理器

bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

bzoj4196[Noi2015]软件包管理器

BZOJ_4196_[Noi2015]软件包管理器_树链剖分