洛谷 2146 [NOI2015]软件包管理器

【题解】

  每个软件只依赖另一个软件,且依赖关系不构成环,那么很容易想到这是树形结构。

  我们用1表示以安装,用0表示未安装或已卸载;那么安装一个软件,就是把它到树根的路径上所有的点都改为1;卸载一个软件,就是把它的子树全部改为0.

  状态改变的软件包数就是操作前后整棵树的点权和。

  这样我们直接树链剖分即可。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<vector>
 5 #define LL long long
 6 #define rg register
 7 #define N 100010
 8 #define ls (u<<1)
 9 #define rs (u<<1|1)
10 #define mid ((a[u].l+a[u].r)>>1)
11 #define len(x) (a[x].r-a[x].l+1)
12 using namespace std;
13 int n,m,cnt,last,fa[N],hvy[N],top[N],dep[N],siz[N],dfn[N];
14 vector<int>son[N];
15 struct tree{
16     int l,r,sum; bool mark;
17 }a[N<<2];
18 inline int read(){
19     int k=0,f=1; char c=getchar();
20     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
21     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
22     return k*f;
23 }
24 void dfs1(int x){
25     siz[x]=1;
26     for(rg int i=0,to;i<son[x].size();i++){
27         dfs1(to=son[x][i]); siz[x]+=siz[to];
28         if(siz[to]>siz[hvy[x]]) hvy[x]=to;
29     }
30 }
31 void dfs2(int x,int tp){
32     top[x]=tp; dfn[x]=++cnt;
33     if(hvy[x]) dfs2(hvy[x],tp);
34     for(rg int i=0,to;i<son[x].size();i++)
35         if((to=son[x][i])!=hvy[x]) dfs2(to,to);
36 }
37 void build(int u,int l,int r){
38     a[u].l=l; a[u].r=r;
39     if(l<r) build(ls,l,mid),build(rs,mid+1,r);
40 }
41 inline void pushdown(int u){
42     a[u].mark=0; a[ls].mark=a[rs].mark=1;
43     if(a[u].sum) a[ls].sum=len(ls),a[rs].sum=len(rs);
44     else a[ls].sum=a[rs].sum=0;
45 }
46 void update(int u,int l,int r,bool type){//type==1-->install
47     if(l<=a[u].l&&a[u].r<=r){
48         a[u].sum=type?len(u):0;
49         a[u].mark=1;
50         return;
51     }
52     if(a[u].mark) pushdown(u);
53     if(l<=mid) update(ls,l,r,type);
54     if(r>mid) update(rs,l,r,type);
55     a[u].sum=a[ls].sum+a[rs].sum;
56 }
57 //int query(int u,int l,int r){
58 //    if(l<=a[u].l&&a[u].r<=r) return a[u].sum;
59 //    if(a[u].mark) pushdown(u); int ret=0;
60 //    if(l<=mid) ret=query(ls,l,r);
61 //    if(r>mid) ret+=query(rs,l,r);
62 //    return ret;
63 //}
64 int main(){
65     n=read();
66     for(rg int i=2;i<=n;i++){
67         int f=read()+1;
68         fa[i]=f; dep[i]=dep[f]+1;
69         son[f].push_back(i);
70     }
71     dfs1(1); dfs2(1,1); build(1,1,n);
72 //    for(rg int i=1;i<=n;i++) printf("%d ",siz[i]); puts("siz");
73     m=read();
74     while(m--){
75         char c=getchar(); while(c!='i'&&c!='u') c=getchar();
76         int x=read()+1;
77         if(c=='i'){
78             int t=top[x];
79             while(x){
80                 update(1,dfn[t],dfn[x],1);
81                 x=fa[t]; t=top[x];
82             }
83         }
84         else update(1,dfn[x],dfn[x]+siz[x]-1,0);
85         printf("%d\n",abs(a[1].sum-last),a[1].sum); last=a[1].sum;
86     }
87     return 0;
88 }
View Code

猜你喜欢

转载自www.cnblogs.com/DriverLao/p/9381085.html