Description
Linux users and OSX users must not be unfamiliar with the package manager. With the Package Manager, you can install a package from a single line of commands, and then the Package Manager will help you download the package from the software source, and automatically resolve all dependencies (that is, other packages that are dependent on downloading the installation of this package) to complete all configurations. The Apt-get,fedora/centos used by Debian/ubuntu and the homebrew available under OSX are excellent package managers.
You decide to design your own package Manager. Inevitably, you need to solve the dependencies between packages. If package a relies on package B, you must install package B before you install package A. Also, if you want to uninstall package B, you must uninstall package a. Now you've got all the dependencies between the packages. And, because of your previous work, in addition to the No. 0 package, the packages in your manager will depend on one and only one package, and the No. 0 package does not depend on any one package. Dependency does not exist ring (if there is M (m≥2) package a1,a2,a3,..., am, where A1 relies on a2,a2 dependency a3,a3 dependency a4,......,am?1 dependent am, and am relies on A1, it is said that the dependencies of M packages form a ring), Of course there will not be a package that relies on itself.
Now you need to write a dependency resolver for your package manager. Based on feedback, users want to quickly know when a package is installed and uninstalled how many packages are installed (that is, how many packages are installed, or how many installed packages are uninstalled), and your task is to implement this section. Note that installing an installed package, or uninstalling a package that is not installed, will not change the installation state of any packages, in which case the number of packages changing the installation state is 0.
Input
The 1th line of the input file contains 1 positive integer n, which indicates the total number of packages. The package is numbered starting from 0.
The following line contains n?1 integers, separated by a single space between adjacent integers, representing the number of packages on which the,..., n?2,n?1 package depends.
The next line contains 1 positive integer q, which indicates the total number of queries.
After Q line, 1 queries per line. There are two types of inquiries:
INSTALLX: Indicates installation package X
UNINSTALLX: means uninstalling package X
You need to maintain the installation status of each package and all packages are not installed at the beginning. For each operation, you need to output this step to change the installation state of how many packages, and then apply this action (that is, change the installation state of your maintenance).
Output
The output file includes the Q line.
The output file of line I outputs 1 integers, the number of packages that change the installation state for step I operations.
Sample Input
7
0 0 0 1 1 5
5
Install 5
Install 6
Uninstall 1
Install 4
Uninstall 0
Sample Output
3
1
3
2
3
HINT
All packages are not installed at the beginning.
Installing the 5th package requires the installation of 0,1,5 three packages.
After installing the 6th package, you only need to install the number 6th package. 0,1,5,6 Four packages are installed at this time.
Uninstalling the 1th package requires uninstalling 1,5,6 three packages. Only the No. 0 package is in the installation state at this time.
After installing the 4th package, you need to install 1, 42 packages. At this point the 0,1,4 is in the installation state.
Finally, uninstalling the NO. 0 package will uninstall all packages.
n=100000
q=100000
Source
Uninstall is to maintain subtree information, installation is to maintain the node to the root node path information.
Bare-chain profile.
When I did it, I sent a chain-bottom.
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define MAXN 100010#define Lchild Rt<<1,l,mid#define Rchild Rt<<1|1,mid+1,r#define LN rt<<1#define RN Rt<<1|1#define MAXINT 0x7fffffffusing namespace STD;intN,q,top,top;structseg{intL,r;intnum[2],flag;} tree[maxn<<2];structedge{intto; Edge *next;} e[maxn*2],*PREV[MAXN];intsize[maxn],chain[maxn],bot[maxn],num[maxn],fa[maxn][ -],DEEP[MAXN],ROOT[MAXN];//chain chain top bot chain Bottom root x is the right interval of the treeBOOLVIS[MAXN];inline intLcaintAintb) {if(Deep[a]<deep[b]) swap (A, b);intT=DEEP[A]-DEEP[B]; for(intI=0; i<= -; i++)if(t& (1<<i)) A=fa[a][i]; for(intI= -; i>=0; i--)if(Fa[a][i]!=fa[b][i]) {A=fa[a][i]; B=fa[b][i]; }if(a==b)returnAElse returnfa[a][0];}inline voidDFS1 (intx) {vis[x]=1; size[x]=1; for(intI=1; i<= -; i++) {if(1<<I>DEEP[X]) Break; fa[x][i]=fa[fa[x][i-1]][i-1]; } for(Edge *i=prev[x];i;i=i->next) {intt=i->to;if(Vis[t])Continue; fa[t][0]=x;deep[t]=deep[x]+1; DFS1 (t); SIZE[X]+=SIZE[T]; }}inline voidDFS2 (intXintLast) {intt=100001; Chain[x]=last;num[x]=++top;root[x]=top;if(Deep[bot[chain[x]]]<deep[x]) bot[chain[x]]=x; for(Edge *i=prev[x];i;i=i->next)if(Deep[i->to]>deep[x]&&size[i->to]>size[t]) t=i->to;if(t>n)return; DFS2 (T,last); for(Edge *i=prev[x];i;i=i->next)if(deep[i->to]>deep[x]&&i->to!=t) DFS2 (i->to,i->to); Root[x]=top;}inline voidInint&X) {CharCh=getchar (); x=0; while(! (ch>=' 0 '&&ch<=' 9 ')) Ch=getchar (); while(ch>=' 0 '&&ch<=' 9 ') x=x*Ten+ch-' 0 ', Ch=getchar ();}inline voidInsertintUintV) {E[++top].to=v;e[top].next=prev[u];p rev[u]=&e[top];}inline voidPUSH_UP (intRT) {tree[rt].num[0]=tree[ln].num[0]+tree[rn].num[0]; tree[rt].num[1]=tree[ln].num[1]+tree[rn].num[1];}inline voidPush_down (intRT) {intB=tree[rt].flag;if(TREE[RT].L==TREE[RT].R)return;if(B!=-maxint) {tree[ln].num[b]=tree[ln].r-tree[ln].l+1; tree[ln].num[!b]=0; tree[rn].num[b]=tree[rn].r-tree[rn].l+1; tree[rn].num[!b]=0; Tree[ln].flag=tree[rn].flag=b; } Tree[rt].flag=-maxint;}inline voidBuildintrt=1,intL=1,intr=n) {tree[rt].l=l;tree[rt].r=r;if(L==R) {tree[rt].num[0]=1; tree[rt].flag=-maxint;return; }intMid= (l+r) >>1; Build (Lchild); build (Rchild); PUSH_UP (RT);}inline voidModifyintRtintLintRintDelta) {if(r<l) swap (L,R); Push_down (RT);intL=tree[rt].l,r=tree[rt].r,mid= (l+r) >>1;if(L<=L&&R>=R) {tree[rt].num[delta]=r-l+1; tree[rt].num[!delta]=0; Tree[rt].flag=delta;return; }if(r<=mid) modify (Ln,l,r,delta);Else if(l>mid) modify (Rn,l,r,delta);ElseModify (Ln,l,mid,delta), modify (rn,mid+1, R,delta); PUSH_UP (RT);}inline voidModify (intAintBintDelta) { while(Chain[a]!=chain[b]) {Modify (1, Num[chain[a]],num[a],delta); a=fa[chain[a]][0]; } Modify (1, Num[b],num[a],delta);}inline intQueryintRtintLintRintFlag) {if(r<l) swap (L,R); Push_down (RT);intL=tree[rt].l,r=tree[rt].r,mid= (l+r) >>1;if(L<=L&&R>=R)returnTree[rt].num[flag];if(R<=mid)returnQuery (Ln,l,r,flag);if(L>mid)returnQuery (Rn,l,r,flag);returnQuery (Ln,l,mid,flag) +query (rn,mid+1, R,flag);}inline intQuery (intAintBintFlag) {intret=0; while(Chain[a]!=chain[b]) {Ret+=query (1, Num[chain[a]],num[a],flag); a=fa[chain[a]][0]; } ret+=query (1, Num[b],num[a],flag);returnRET;}intMain () {in (n); for(intI=0; i<n;i++) root[i]=i; for(intI=1; i<n;i++) {intF;in (f); Insert (f,i); insert (I,F); } build (); DFS1 (0); DFS2 (0,0); In (q);Charch[Ten];intU while(q--) {scanf('%s ', ch);if(ch[0]==' I ') {in (U);intNum; Num=query (U,0,0); Modify (U,0,1);printf("%d\n", Num); }Else{in (U);intNum; Num=query (1, Num[u],root[u],1); Modify1, Num[u],root[u],0);printf("%d\n", Num); } }}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
"NOI2015" "BZOJ4196" Package Manager