洛谷 [P2146] 软件包管理器

树剖

将一个软件是否安装,看作是sum数组的0或1,对于每个操作前后sum[1]的变化,就是所求

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
const int MAXN=1000005;
int init(){
	int rv=0,fh=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') fh=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		rv=(rv<<1)+(rv<<3)+c-'0';
		c=getchar();
	}
	return fh*rv;
}
int head[MAXN],top[MAXN],id[MAXN],son[MAXN],n,m,nume,ind,siz[MAXN],dep[MAXN],fa[MAXN];
struct edge{
	int to,nxt;
}e[MAXN<<1];
void adde(int from,int to){
	e[++nume].to=to;
	e[nume].nxt=head[from];
	head[from]=nume;
}
void dfs1(int u,int rt){
	dep[u]=dep[rt]+1;
	siz[u]=1;
	int ma=0;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa[u]) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>ma){
			ma=siz[v];
			son[u]=v;
		}
	}
}
void dfs2(int u,int topf){
	top[u]=topf;
	id[u]=++ind;
	if(!son[u]) return;
	dfs2(son[u],topf);
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}
struct SGT{
	int sum[MAXN<<2],tag[MAXN<<2];
	void PushUp(int rt){
		sum[rt]=sum[rt<<1]+sum[rt<<1|1];
	}
	void build(int l,int r,int rt){
		if(l==r){
			sum[rt]=0;return;
		}
		int mid=(l+r)>>1;
		build(lson);
		build(rson);
		PushUp(rt);
	}
	void PushDown(int rt,int m){
		if(tag[rt]){
			if(tag[rt]==1){
				tag[rt<<1]=tag[rt<<1|1]=tag[rt];
				sum[rt<<1]=sum[rt<<1|1]=0;
				tag[rt]=0;
			}else{
				tag[rt<<1]=tag[rt<<1|1]=tag[rt];
				sum[rt<<1]=(m-(m>>1));
				sum[rt<<1|1]=m>>1;
				tag[rt]=0;
			}
		}
	}
	void Update(int L,int R,int op,int l,int r,int rt){
		if(L<=l&&r<=R){
			if(op==1){
				sum[rt]=0;
				tag[rt]=1;
			}else {
				sum[rt]=r-l+1;
				tag[rt]=2;
			}
			return;
		}
		PushDown(rt,r-l+1);
		int mid=(l+r)>>1;
		if(L<=mid) Update(L,R,op,lson);
		if(mid<R) Update(L,R,op,rson);
		PushUp(rt);
	}
}sgt;
void install(int x){
	int t=sgt.sum[1];
	while(top[x]!=1){
		sgt.Update(id[top[x]],id[x],2,1,n,1);
		x=fa[top[x]];
	}
	sgt.Update(1,id[x],2,1,n,1);
	printf("%d
",sgt.sum[1]-t);
}
void uninstall(int x){
	int t=sgt.sum[1];
	sgt.Update(id[x],id[x]+siz[x]-1,1,1,n,1);
	printf("%d
",t-sgt.sum[1]);
}
int main(){
	n=init();
	for(int i=2;i<=n;i++) fa[i]=init()+1,adde(i,fa[i]),adde(fa[i],i);
	m=init();
	dep[1]=1;
	dfs1(1,0);
	dfs2(1,1);
	char s[20];
	for(int i=1;i<=m;i++){
		scanf("%s",s);
		int t=init()+1;
		if(s[0]=='i'){
			install(t);
		}else{
			uninstall(t);
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8410596.html