【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\n",work1(a+1)); 163 else 164 printf("%d\n",work2(a+1)); 165 } 166 return 0; 167 }