BZOJ 4196 软件包管理器(树链剖分子树)
来源:互联网 发布:java的发展趋势 编辑:程序博客网 时间:2024/06/05 18:32
树链剖分同时记录子树区间
对于install操作,直接爬上根结点,进行更新查询操作
对于unstall操作,直接询问子树区间,更新子树区间
#include<cstring>#include<string>#include<iostream>#include<queue>#include<cstdio>#include<algorithm>#include<map>#include<cstdlib>#include<cmath>#include<vector>//#pragma comment(linker, "/STACK:1024000000,1024000000");using namespace std;#define INF 0x3f3f3f3f#define maxn 300005int fir[maxn],nex[maxn],v[maxn],e_max;int son[maxn],fa[maxn],top[maxn],siz[maxn],deep[maxn],tot;int in[maxn],out[maxn];int sum[2*maxn],tag[2*maxn];void init_(){ memset(fir,-1,sizeof fir); memset(son,-1,sizeof son); memset(in,0,sizeof in); memset(out,0,sizeof out); e_max=0; tot=1;}void add_edge(int s,int t){ int e=e_max++; v[e]=t; nex[e]=fir[s]; fir[s]=e;}void dfs1(int k,int pre,int d){ deep[k]=d; siz[k]=1; fa[k]=pre; for(int i=fir[k];~i;i=nex[i]) { int e=v[i]; if(e!=pre) { dfs1(e,k,d+1); siz[k]+=siz[e]; if(son[k]==-1||siz[son[k]]<siz[e]) son[k]=e; } }}void dfs2(int k,int sp){ top[k]=sp; in[k]=tot++; out[k]=in[k]; if(son[k]==-1) return ; dfs2(son[k],sp); out[k]=max(out[k],out[son[k]]); for(int i=fir[k];~i;i=nex[i]) { int e=v[i]; if(e!=son[k]&&e!=fa[k]) { dfs2(e,e); out[k]=max(out[k],out[e]); } }}void init(int l,int r,int k){ tag[k]=-1; if(l==r) { sum[k]=1; return ; } int mid=l+r>>1; init(l,mid,k<<1); init(mid+1,r,k<<1|1); sum[k]=sum[k<<1]+sum[k<<1|1];}void pushdown(int l,int r,int k){ if(tag[k]==-1) return ; int mid=l+r>>1; tag[k<<1]=tag[k<<1|1]=tag[k]; if(tag[k]) sum[k<<1]=mid-l+1,sum[k<<1|1]=r-mid; else sum[k<<1]=sum[k<<1|1]=0; tag[k]=-1;}void update(int d,int s,int t,int l,int r,int k){ if(s==l&&r==t) { tag[k]=d; if(d) sum[k]=r-l+1; else sum[k]=0; return ; } pushdown(l,r,k); int mid=l+r>>1; if(t<=mid) update(d,s,t,l,mid,k<<1); else if(s>mid) update(d,s,t,mid+1,r,k<<1|1); else { update(d,s,mid,l,mid,k<<1); update(d,mid+1,t,mid+1,r,k<<1|1); } sum[k]=sum[k<<1]+sum[k<<1|1];}int query(int s,int t,int l,int r,int k){ if(s==l&&r==t) { return sum[k]; } pushdown(l,r,k); int mid=l+r>>1; if(t<=mid) return query(s,t,l,mid,k<<1); else if(s>mid) return query(s,t,mid+1,r,k<<1|1); else return query(s,mid,l,mid,k<<1)+query(mid+1,t,mid+1,r,k<<1|1);}int Query(int s,int t){ int ans=0; int f1=top[s],f2=top[t]; while(f1!=f2) { if(deep[f1]<deep[f2]) swap(f1,f2),swap(s,t); ans+=query(in[f1],in[s],1,tot-1,1); update(0,in[f1],in[s],1,tot-1,1); s=fa[f1]; f1=top[s]; } if(deep[s]>deep[t]) swap(s,t); ans+=query(in[s],in[t],1,tot-1,1); update(0,in[s],in[t],1,tot-1,1); return ans;}int main(){ int n; while(scanf("%d",&n)!=EOF) { init_(); for(int i=1;i<n;i++) { int a; scanf("%d",&a); add_edge(a,i); add_edge(i,a); } dfs1(0,-1,1); dfs2(0,0); init(1,tot-1,1); int m; scanf("%d",&m); while(m--) { char s[20]; int x; scanf("%s%d",s,&x); if(!strcmp(s,"install")) { if(!query(in[x],in[x],1,tot-1,1)) { printf("0\n"); continue; } int ans=Query(x,0); printf("%d\n",ans); } else { if(query(in[x],in[x],1,tot-1,1)) { printf("0\n"); continue; } printf("%d\n",siz[x]-query(in[x],out[x],1,tot-1,1)); update(1,in[x],out[x],1,tot-1,1); } } } return 0;}
0 0
- BZOJ 4196 软件包管理器(树链剖分子树)
- 【树链剖分】[BZOJ 4196]软件包管理器
- BZOJ-4196 软件包管理器 树链剖分
- 【树链剖分】【NOI 2015】【bzoj 4196】软件包管理器
- 【树链剖分】[BZOJ 4196][NOI 2014]软件包管理器
- BZOJ 4196([Noi2015]软件包管理器-树链剖分)
- BZOJ 4196: [Noi2015]软件包管理器 树链剖分
- [BZOJ 4196][Noi2015]软件包管理器
- bzoj 4196: [Noi2015]软件包管理器
- BZOJ 4196 [Noi2015]软件包管理器
- bzoj 4196: [Noi2015]软件包管理器
- BZOJ 4196 [Noi2015]软件包管理器
- 【NOI2015T2】软件包管理器-树链剖分维护路径和子树信息
- |BZOJ 4196|树链剖分|线段树|[Noi2015]软件包管理器
- bzoj-4196 NOI-2015 软件包管理器
- BZOJ[4196][Noi2015]洛谷[2146]软件包管理器
- 4196: [Noi2015]软件包管理器
- HYSBZ 4196 软件包管理器
- AssetBundle创建,加载,5.1版本
- 链栈的认识(2)
- mvc,mvp,mvvm 设计框架的比较和分析
- PAT-A 1099. Build A Binary Search Tree
- 【可视化】VTK的图层结构与置顶显示
- BZOJ 4196 软件包管理器(树链剖分子树)
- 有人向我反馈了一个bug
- [OpenCv]Win10 X64 + VS2015 + CMake3.6.1 编译OpenCv3.1.0记录
- android开发中Settings结构简单分析
- 简单的C++反射实现
- easyui中datagrid动态绑定json加载列的解决方案
- C++ STL 容器
- POJ1753翻转游戏(题目大意+理解)
- 网络编程(一):网络基础之一