[NOI2015]软件包管理器

嘟嘟嘟

这明显就是一道树剖的水题~~~

install操作就是查询x到根节点的路径中0的个数,并且每一个节点的权值都改成1.

uninstall就是查询x的子树中1的个数,并都改成0.

有一个优化就是install操作中如果当前区间已经有1了,就可以不用往上查,直接返回。因为从题中可以得到一个信息,如果有一个点的权值是1,那么他祖先的所有节点一定都是1。

嗯,完了。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9 #include<stack>
 10 #include<queue>
 11 using namespace std;
 12 #define enter puts("") 
 13 #define space putchar(' ')
 14 #define Mem(a, x) memset(a, x, sizeof(a))
 15 #define rg register
 16 typedef long long ll;
 17 typedef double db;
 18 const int INF = 0x3f3f3f3f;
 19 const db eps = 1e-8;
 20 const int maxn = 1e5 + 5;
 21 inline ll read()
 22 {
 23     ll ans = 0;
 24     char ch = getchar(), last = ' ';
 25     while(!isdigit(ch)) {last = ch; ch = getchar();}
 26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
 27     if(last == '-') ans = -ans;
 28     return ans;
 29 }
 30 inline void write(ll x)
 31 {
 32     if(x < 0) x = -x, putchar('-');
 33     if(x >= 10) write(x / 10);
 34     putchar(x % 10 + '0');
 35 }
 36 
 37 int n, m;
 38 vector<int> v[maxn];
 39 
 40 int dep[maxn], fa[maxn], siz[maxn], son[maxn];
 41 void dfs1(int now)
 42 {
 43     siz[now] = 1;
 44     for(int i = 0; i < (int)v[now].size(); ++i)
 45     {
 46         dep[v[now][i]] = dep[now] + 1;
 47         fa[v[now][i]] = now;
 48         dfs1(v[now][i]);
 49         siz[now] += siz[v[now][i]];
 50         if(!son[now] || siz[son[now]] < siz[v[now][i]]) son[now] = v[now][i];
 51     }
 52 }
 53 int dfsx[maxn], pos[maxn], top[maxn], cnt = 0;
 54 void dfs2(int now)
 55 {
 56     dfsx[now] = ++cnt; pos[cnt] = now;
 57     if(son[now])
 58     {
 59         top[son[now]] = top[now];
 60         dfs2(son[now]);
 61     }
 62     for(int i = 0; i < (int)v[now].size(); ++i)
 63     {
 64         if(v[now][i] != son[now])
 65         {
 66             top[v[now][i]] = v[now][i];
 67             dfs2(v[now][i]);
 68         }
 69     }
 70 }
 71 
 72 int l[maxn << 2], r[maxn << 2], sum[maxn << 2], lzy[maxn << 2];
 73 void build(int L, int R, int now)
 74 {
 75     l[now] = L; r[now] = R;
 76     lzy[now] = -1;
 77     if(L == R) return;
 78     int mid = (L + R) >> 1;
 79     build(L, mid, now << 1);
 80     build(mid + 1, R, now << 1 | 1);
 81 }
 82 void pushdown(int now)
 83 {
 84     if(lzy[now] != -1)
 85     {
 86         sum[now << 1] = (r[now << 1] - l[now << 1] + 1) * lzy[now];
 87         sum[now << 1 | 1] = (r[now << 1 | 1] - l[now << 1 | 1] + 1) * lzy[now];
 88         lzy[now << 1] = lzy[now << 1 | 1] = lzy[now];
 89         lzy[now] = -1;
 90     }
 91 }
 92 void update(int L, int R, int now, bool flg)
 93 {
 94     if(L == l[now] && R == r[now]) 
 95     {
 96         sum[now] = (R - L + 1) * flg;
 97         lzy[now] = flg; return;
 98     }
 99     pushdown(now);
100     int mid = (l[now] + r[now]) >> 1;
101     if(R <= mid) update(L, R, now << 1, flg);
102     else if(L > mid) update(L, R, now << 1 | 1, flg);
103     else update(L, mid, now << 1, flg), update(mid + 1, R, now << 1 | 1, flg);
104     sum[now] = sum[now << 1] + sum[now << 1 | 1]; 
105 }
106 int query(int L, int R, int now)
107 {
108     if(L == l[now] && R == r[now]) return sum[now];
109     pushdown(now);
110     int mid = (l[now] + r[now]) >> 1;
111     if(R <= mid) return query(L, R, now << 1);
112     else if(L > mid) return query(L, R, now << 1 | 1);
113     else return query(L, mid, now << 1) + query(mid + 1, R, now << 1 | 1);
114 }
115 
116 int query_in(int x)
117 {
118     int ret = 0;
119     bool flg = 1;
120     while(top[x] != top[1])
121     {
122         int tp = query(dfsx[top[x]], dfsx[x], 1);
123         ret += dfsx[x] - dfsx[top[x]] + 1 - tp;
124         update(dfsx[top[x]], dfsx[x], 1, 1);
125         if(tp) {flg = 0; break;}
126         x = fa[top[x]];
127     }
128     if(!flg) return ret;
129     ret += dfsx[x] - dfsx[1] + 1 - query(dfsx[1], dfsx[x], 1);
130     update(dfsx[1], dfsx[x], 1, 1);
131     return ret;
132 }
133 int query_un(int x)
134 {
135     int ret = query(dfsx[x], dfsx[x] + siz[x] - 1, 1);
136     update(dfsx[x], dfsx[x] + siz[x] - 1, 1, 0);
137     return ret;
138 }
139 
140 char c[12];
141 
142 int main()
143 {
144     n = read();
145     for(int i = 2; i <= n; ++i) 
146     {
147         int x = read() + 1;
148         v[x].push_back(i);
149     }
150     dfs1(1); top[1] = 1; dfs2(1);
151     build(1, cnt, 1);
152     m = read();
153     for(int i = 1; i <= m; ++i)
154     {
155         scanf("%s", c); int x = read() + 1;
156         if(c[0] == 'i') write(query_in(x)), enter;
157         else write(query_un(x)), enter;
158     }
159     return 0;
160 }
View Code
原文地址:https://www.cnblogs.com/mrclr/p/9700094.html