[Bzoj4196] [Noi2015] package manager --- Split + tree chain segment tree

NOI2015 Package Manager

 Title Description 

    OSX and Linux users to certain user package manager will not be unfamiliar. Through the package manager, you can install a package by a command line, then Package Manager will help you download software packages from source, and automatically resolve all the dependencies (ie, download and install the installation package depends other packages) to complete all of the configuration. apt-get, Fedora / CentOS using yum Debian / Ubuntu uses, as well as homebrew available under OSX are excellent package manager.

You decide to design your own package manager. Inevitably, you have to resolve dependencies between packages. If a package A depends on package B, then A previous installation package, you must first install the software package B. Meanwhile, if you want to uninstall packages B, you must uninstall package A. Now you've got all the dependencies between packages. Moreover, since your previous work, in addition to 0 package, the package will depend on your manager among the one and only one package, but the package does not depend on any number 0 a package. Dependencies present in the ring (if m (m≥2) packages A1, A2, A3, ..., Am, dependencies wherein A1 A2, A2 depend A3, A3 dependent A4, ......, Am-1 dependent Am, and Am rely A1, called the m package dependencies that constitute the ring), and of course there will not be a package depends on their own.
Now you have to write a program to solve rely on your package manager. Based on feedback, when the user wants to install and uninstall a software package, and quickly know which would effectively change the installation state how many packages (ie, the number of installation is not installed package operations will be installed, or uninstall operation unloads how many installed packages), your task is to implement this section. Note that the number of packages to install a software package installed, or uninstall a package is not installed, the installation will not change the status of any package, that is, in this case, change the installation state is zero.

 Enter a description

The first line of the input file contains a positive integer n, the total package. Packages are numbered starting from zero.

Then line comprising n-1 integers, separated by a single space between adjacent integers, respectively 1,2,3, ..., n-2, n-1 dependent packages No. package number.
The next line contains a positive integer q, represents the total number of inquiries.
After the q rows of a query. Inquiry is divided into two types:
installx: x represents the installation package
uninstallx: x represents uninstall packages
You need to maintain the status of each package install, start all packages are not installed in the state. For each operation, you need to output this operation will be the number of packages installed state change, subsequent application of this operation (ie you change the installation state of maintenance).

 Output Description

Output file including q rows.

I-th row of the output file output an integer, the i-th step operation to change the number of packages mounted state.

 

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

2

 

 Obviously this is a tree , so let's be the skilled throwing feces tree chain segment tree split + ~

 And only need to record how many software updates within the range of installation on the line

 Update subtree time, because the distribution point of the segment tree is actually a heavy chain DFS order of priority

 So that the update interval subtree is [id [x], id [x] + size [x] -1] friends

 Pay several times before A

 A previous RE

 1e5 2e5 change becomes TLE (but do not know why RE )

 Then find the topic of inquiry and change are tied together

 Put the query and modify the change to a function in

 Then A friends ~

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#define M 200010
using namespace std;
int n,q,size[M],dep[M],fa[M],rk[M],id[M];
int k,cnt,head[M],son[M],top[M],sum[M*2],lazy[M];
struct node {
	int to,next;
}e[M];
void add(int x,int y) {
	e[k].to = y; e[k].next = head[x];
	head[x] = k++;
}
void init() {
	k=0; cnt=0;
	for (int i=0;i<=n;i++) {
		size[i] = son[i] = 0;
		head[i] = lazy[i] = -1;
		sum[i] = sum[i+n] = 0;
	}
}
void dfs1(int s,int d) {
	dep[s] = d;
	size[s] = 1;
	for (int i=head[s];~i;i=e[i].next)
	if ( e[i].to != fa[s] ) {
		dfs1(e[i].to,d+1);
		size[s] += size[e[i].to];
		if ( size[e[i].to] > size[son[s]] )
			son[s] = e[i].to;
	}
} 
void dfs2(int s,int t) {
	top[s] = t;
	id[s] = ++cnt;
	rk[cnt] = s;
	if ( !son[s] ) return;
	dfs2(son[s],t);
	for (int i=head[s];~i;i=e[i].next)
	if ( e[i].to != fa[s] && e[i].to != son[s] )
		dfs2(e[i].to,e[i].to);
}
void pushup(int x) {
	sum[x] = sum[x*2] + sum[x*2+1];
}
void pushdown(int l,int r,int x) {
	if ( lazy[x] != -1 ) {
		int mid = (l+r)/2;
		sum[x*2] = (mid-l+1)*lazy[x];
		lazy[x*2] = lazy[x];
		sum[x*2+1] = (r-mid)*lazy[x];
		lazy[x*2+1] = lazy[x];
		lazy[x] = -1;
	}
}
void update(int L,int R,int x,int l,int r,int a) {
	if ( l<=L&&R<=r ) {
		lazy[x] = a;
		sum[x] = a*(R-L+1);
		return;
	}
	pushdown(L,R,x);
	int mid=(L+R)/2;
	if ( l<=mid )
		update(L,mid,x*2,l,r,a);
	if ( mid < r )
		update(mid+1,R,x*2+1,l,r,a);
	pushup(x);
}
void updates(int x) {
	while ( top[x] != 1 ) {
		update(1,n,1,id[top[x]],id[x],1);
		x=fa[top[x]];
	}
	update(1,n,1,1,id[x],1);
}
int query(int L,int R,int x,int l,int r,int a) {
	int ret = 0;
	if ( l<=L&&R<=r ) {
		ret = sum[x];
		sum[x] = a*(R-L+1);
		lazy[x] = a;
		return ret;
	}
	pushdown(L,R,x);
	int mid = (L+R)/2;
	if ( l<=mid ) 
		ret+=query(L,mid,x*2,l,r,a);
	if ( mid < r)
		ret+=query(mid+1,R,x*2+1,l,r,a);
	pushup(x);
	return ret;
}
int Que(int x) {
	int ret=0;
	while ( top[x] != 1 ) {
		ret+=query(1,n,1,id[top[x]],id[x],1);
		x=fa[top[x]];
	}
	ret += query(1,n,1,1,id[x],1);
	return ret;
}
int main() {
	cin>>n;
	init();
	fa[1] = 1;
	for (int i=2;i<=n;i++) {
		scanf("%d",&fa[i]);
		fa[i]++;
		add(fa[i],i);
	}
	dfs1(1,1);
	dfs2(1,1);
	char op[2];
	int a,ans;
	cin>>q;
	for (int i=1;i<=q;i++) {
		scanf("%s %d",op,&a);
		a++;
		if ( op[0] == 'i' ) {
			ans = dep[a] - Que(a);
			printf("%d\n",ans);
		}
		else {
			ans = query(1,n,1,id[a],id[a]+size[a]-1,0);
			printf("%d\n",ans);
		}
	}
	return 0;
}

 

  

 

Guess you like

Origin www.cnblogs.com/JachinYiXuan/p/11226734.html