zoukankan      html  css  js  c++  java
  • 洛谷 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
    ",abs(a[1].sum-last),a[1].sum); last=a[1].sum;
    86     }
    87     return 0;
    88 }
    View Code
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 黑色星期五
    Java实现 蓝桥杯VIP 算法训练 比赛安排
    Java实现 蓝桥杯VIP 算法训练 比赛安排
    Java实现 蓝桥杯VIP 算法训练 斜率计算
    Java实现 蓝桥杯VIP 算法训练 斜率计算
    Java实现 蓝桥杯VIP 算法训练 整数平均值
    Java实现 蓝桥杯VIP 算法训练 整数平均值
    控件动态产生器(使用RegisterClasses提前进行注册)
    Delphi编写自定义控件以及接口的使用(做了一个TpgDbEdit)
    Log4delphi使用心得
  • 原文地址:https://www.cnblogs.com/DriverLao/p/9381085.html
Copyright © 2011-2022 走看看