LOJ 2130 软件包管理器

熟练剖分

路径到根直接向上跳

#include <iostream>
#include <cassert>
#include <string>

using namespace std;

const int MAXN=101111;

int N, M;
int P;
string com;

struct Vert{
	int Fa, Son, Bro;
	int Size, Dep;
	int MainSon, Top;
	int Dps, Dpr;
} V[MAXN];

void DFS1(int at){
	V[at].Size=1;
	for(int to=V[at].Son;to>0;to=V[to].Bro){
		V[to].Dep=V[at].Dep+1;
		DFS1(to);
		V[at].Size+=V[to].Size;
		if(V[at].MainSon<=0 || V[to].Size>V[V[at].MainSon].Size)	V[at].MainSon=to;
	}
}

int Dfn[MAXN], DFN;

void DFS2(int at, int t){
	++DFN;
	Dfn[DFN]=at;V[at].Dps=DFN;
	V[at].Top=t;
	if(V[at].MainSon>0)	DFS2(V[at].MainSon, t);
	for(int to=V[at].Son;to>0;to=V[to].Bro){
		if(to==V[at].MainSon)	continue;
		DFS2(to, to);
	}
	V[at].Dpr=DFN;/**/
}

struct Node{
	int l, r;
	int Sum;
	int opt;
} T[MAXN<<2];

int L, R, op;
int Sum;

void BuildTree(int l, int r, int at){
	T[at].l=l;T[at].r=r;T[at].Sum=0;T[at].opt=-1;
	if(l<r){
		int m=(l+r)>>1;
		BuildTree(l, m, at<<1);
		BuildTree(m+1, r, (at<<1)|1);
	}
}

void opr(int at){
	T[at].Sum=op*(T[at].r-T[at].l+1);
}

void cop(int at){
	T[at].opt=op;
}

void pdw(int at){
	if(T[at].opt==-1)	return;
	int top=op;op=T[at].opt;
	opr(at<<1);cop(at<<1);
	opr((at<<1)|1);cop((at<<1)|1);
	op=top;T[at].opt=-1;
}

void pup(int at){
	T[at].Sum=T[at<<1].Sum+T[(at<<1)|1].Sum;
}

int Ask(int at){
	if(T[at].l>=L && T[at].r<=R){
		return T[at].Sum;
	}
	pdw(at);
	int m=(T[at].l+T[at].r)>>1;
	int ret=0;
	if(L<=m)	ret+=Ask(at<<1);
	if(R>m)	ret+=Ask((at<<1)|1);
	return ret;
}

void Update(int at){
	if(T[at].l>=L && T[at].r<=R){
		T[at].Sum=op*(T[at].r-T[at].l+1);
		T[at].opt=op;
		return;
	}
	pdw(at);
	int m=(T[at].l+T[at].r)>>1;
	if(L<=m)	Update(at<<1);
	if(R>m)	Update((at<<1)|1);
	pup(at);
}

int main(){
	ios_base::sync_with_stdio(false);
	
	cin >> N;
	for(int i=2, f;i<=N;++i){
		cin >> f;++f;
		V[i].Fa=f;V[i].Bro=V[f].Son;V[f].Son=i;
	}
	
	V[1].Dep=1;
	DFS1(1);
	DFS2(1, 1);
	
	assert(DFN==N);
	BuildTree(1, N, 1);
	
	cin >> M;
	while(M--){
		cin >> com >> P;++P;
		Sum=0;
		if(com[0]=='i'){
			op=1;
			for(int k=P;k>0;k=V[V[k].Top].Fa){
				L=V[V[k].Top].Dps;R=V[k].Dps;
				Sum+=Ask(1);
				Update(1);
			}
			cout << V[P].Dep-Sum << endl;
		}
		else{
			op=0;
			L=V[P].Dps;R=V[P].Dpr;
			Sum=Ask(1);
			Update(1);
			cout << Sum << endl;
		}
	}
	
	return 0;
}
posted @ 2018-05-26 20:07  Pickupwin  阅读(138)  评论(0编辑  收藏  举报