zoukankan      html  css  js  c++  java
  • 【bzoj4196】[Noi2015]软件包管理器

    裸的树链剖分。

    对于安装 查询和维护到根路径

    对于卸载 查询和维护子树信息

    一开始线段树add[]标记要全赋值为-1

      1  
      2 
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<cstdlib>
      6 #include<cstring>
      7 #include<cstdio>
      8 #include<cmath>
      9 using namespace std;
     10   
     11 typedef long long LL;
     12   
     13 #define N 200010
     14   
     15 int id;
     16 int fa[N],siz[N],top[N],son[N];
     17 int pos[N],r[N];
     18 LL sum[N<<2],add[N<<2];
     19   
     20 struct Node
     21 {
     22     int to,next;
     23 }e[N];
     24 int head[N];
     25 int cnt;
     26  
     27 int a;
     28  
     29 char s;
     30  
     31 int n,q;
     32  
     33 int read()
     34 {
     35     int x=0,f=1;char ch=getchar();
     36     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     37     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     38     return x*f;
     39 }
     40  
     41 void link(int x,int y)
     42 {
     43     e[++cnt]=(Node){y,head[x]};
     44     head[x]=cnt;
     45 }
     46   
     47 void dfs(int x)
     48 {
     49     siz[x]=1;
     50     for (int i=head[x],mx=0;i;i=e[i].next)
     51         if (e[i].to!=fa[x])
     52         {
     53             fa[e[i].to]=x;
     54             dfs(e[i].to);
     55             siz[x]+=siz[e[i].to];
     56             if (siz[e[i].to]>mx)
     57                 mx=siz[e[i].to],son[x]=e[i].to;
     58         }
     59 }
     60   
     61 void dfs2(int x,int cha)
     62 {
     63     top[x]=cha;
     64     pos[x]=++id;
     65     if (son[x])
     66         dfs2(son[x],cha);
     67     for (int i=head[x];i;i=e[i].next)
     68         if(e[i].to!=fa[x] && e[i].to!=son[x])
     69             dfs2(e[i].to,e[i].to);
     70     r[x]=id;
     71 }
     72  
     73 void pushup(int now)
     74 {
     75     sum[now]=sum[now<<1]+sum[now<<1|1];
     76 }
     77  
     78 void pushdown(int nowl,int nowr,int now,int mid)
     79 {
     80     if (add[now]!=-1)
     81     {
     82         LL t=add[now];
     83         add[now]=-1;
     84         add[now<<1]=t;
     85         add[now<<1|1]=t;
     86         sum[now<<1]=t*(mid-nowl+1);
     87         sum[now<<1|1]=t*(nowr-mid);
     88     }
     89 }
     90   
     91 void update(int nowl,int nowr,int now,int s,int t,LL d)
     92 {
     93     if (nowl>=s && nowr<=t)
     94     {
     95         add[now]=d;
     96         sum[now]=(nowr-nowl+1)*d;
     97         return ;
     98     }
     99     int mid=(nowl+nowr)>>1;
    100     pushdown(nowl,nowr,now,mid);
    101     if (s<=mid)
    102         update(nowl,mid,now<<1,s,t,d);
    103     if (t>mid)
    104         update(mid+1,nowr,now<<1|1,s,t,d);
    105     pushup(now);
    106 }
    107   
    108 int query(int nowl,int nowr,int now,int s,int t)
    109 {
    110     if (nowl>=s && nowr<=t)
    111         return sum[now];
    112     int mid=(nowl+nowr)>>1;
    113     int ans=0;
    114     pushdown(nowl,nowr,now,mid);
    115     if (s<=mid)
    116         ans+=query(nowl,mid,now<<1,s,t);
    117     if (t>mid)
    118         ans+=query(mid+1,nowr,now<<1|1,s,t);
    119     return ans;
    120 }
    121  
    122 int work1(int x)
    123 {
    124     int ans,res=0;
    125     while (x)
    126     {
    127         ans=query(1,n,1,pos[top[x]],pos[x]);
    128         res+=pos[x]-pos[top[x]]+1-ans; 
    129         update(1,n,1,pos[top[x]],pos[x],1); 
    130         if (ans)
    131             break;
    132         x=fa[top[x]];
    133     }
    134     return res;
    135 }
    136  
    137 int work2(int x) 
    138 { 
    139     int res;
    140     res=query(1,n,1,pos[x],r[x]); 
    141     update(1,n,1,pos[x],r[x],0); 
    142     return res; 
    143 }
    144  
    145 int main()
    146 {  
    147      n=read();
    148     for (int i=1;i<n;i++)
    149     {
    150         a=read();
    151         link(a+1,i+1);
    152     }
    153     dfs(1);
    154     dfs2(1,1);
    155     memset(add,-1,sizeof(add));
    156     q=read();
    157     while (q--)
    158     {
    159         scanf("%c",&s);
    160         a=read();
    161         if (s=='i')
    162             printf("%d
    ",work1(a+1));
    163         else
    164             printf("%d
    ",work2(a+1));
    165     }
    166     return 0;
    167 }
  • 相关阅读:
    Dos命令快速设置ip、网关、dns地址
    远程桌面连接保存登陆用户以及密码(凭据)备份方法
    如何启用windows8, windows10中被停用的远程桌面,如何连接windows10远程桌面?
    通过日志恢复SQL Server的历史数据
    http://sourceforge.net/projects/rtspdirectshow/
    iphone上实现H264 硬编码
    利用lipo编译合并iPhone模拟器和真机通用的静态类
    在iOS上使用ffmpeg播放视频
    基于.Net的单点登录(SSO)解决方案
    java实现简单的单点登录
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5335077.html
Copyright © 2011-2022 走看看