蒟蒻求助,树剖写一次挂一次
查看原帖
蒟蒻求助,树剖写一次挂一次
193158
michael_song楼主2020/8/23 10:15
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int M=100005;
int n,q;
int w[M],cnt,head[M];
int fa[M],siz[M],deep[M],hson[M],top[M],id[M],a[M];
int tmax[M<<2],tmin[M<<2],tsum[M<<2],tag[M<<2];
bool vis[M];
char ins[1000];
struct edge
{
	int v,next;
}e[M<<1];
void addedge(int u,int v)
{
	e[++cnt].v=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int maxn(int a,int b)
{
	if(a>b)
		return a;
	else
		return b;
}
int minn(int a,int b)
{
	if(a<b)
		return a;
	else
		return b; 
}
int ls(int x)
{
	return x<<1;
}
int rs(int x)
{
	return x<<1|1;
}
int read()
{
	int w=1,f=0;
	char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-')
			w=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		f=f*10+c-'0';
		c=getchar();
	}
	return w*f;
}
void dfs1(int p,int father,int d)
{
	siz[p]=1;
	fa[p]=father;
	deep[p]=d;
	int ms=0;
	for(int i=head[p];i;i=e[i].next)
	{
		int v=e[i].v;
		if(v==father)
			continue; 
		if(v!=father)
			dfs1(v,p,d+1);
		siz[p]+=siz[v];	
		if(siz[v]>ms)//锅出在这里!! 
		{
			hson[p]=v;
			ms=siz[v];
		}
	}	
}
void dfs2(int p,int topf)
{
	id[p]=++cnt;//!!!!!
	top[p]=topf;
	a[cnt]=0;//所以不用建树 
	if(!hson[p])
		return;//!!
	dfs2(hson[p],topf);
	for(int i=head[p];i;i=e[i].next)
	{
		int v=e[i].v;
		if(v!=fa[p]&&v!=hson[p])
			dfs2(v,v);
	}
}
void push_up(int p)
{
	tmax[p]=maxn(tmax[ls(p)],tmax[rs(p)]);
	tmin[p]=minn(tmin[ls(p)],tmin[rs(p)]);
//	tsum[p]=tsum[ls(p)]+tsum[rs(p)];

}
/*
void f(int p,int l,int r,int k)
{
	tag[p]+=k;
	tsum[p]+=(r-l+1)*k;
}
void pushdown(int p,int l,int r)
{
	int mid=(l+r)>>1;
	f(ls(p),l,mid,tag[p]);
	f(rs(p),mid+1,r,tag[p]);
	tag[p]=0;
}
*/
void update(int nl,int nr,int l,int r,int p,int k)
{
	if(nl<=l&&r<=nr)
	{
		tmax[p]=k;
		tmin[p]=k;
		return;
	}
	int mid=(l+r)>>1;
	if(nl<=mid)
		update(nl,nr,l,mid,ls(p),k);
	if(nr>mid)
		update(nl,nr,mid+1,r,rs(p),k);
	push_up(p);
}
int q0(int nl,int nr,int l,int r,int p)
{
	int ans=0;
	if(nl<=l&&r<=nr)
	{
		if(tmax[p]==0)
			return r-l+1;
		if(tmin[p]==1)	
			return 0;
	}
	int mid=(l+r)>>1;
	if(nl<=mid)
		ans+=q0(nl,nr,l,mid,ls(p));
	if(nr>mid)
		ans+=q0(nl,nr,mid+1,r,rs(p));
	return ans;
		
}
int q1(int nl,int nr,int l,int r,int p)//可能要重写! 
{
	int ans=0;
	if(nl<=l&&r<=nr)
	{
		if(tmin[p]==1)
			return r-l+1;
		if(tmax[p]==0)	
			return 0;
	}
	int mid=(l+r)>>1;
	if(nl<=mid)
		ans+=q1(nl,nr,l,mid,ls(p));
	if(nr>mid)
		ans+=q1(nl,nr,mid+1,r,rs(p));
	return ans;
}
void uR(int x,int y,int z)
{
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]])
			swap(x,y);
		update(id[top[x]],id[x],1,n,1,z);
		x=fa[top[x]];
	}
	if(deep[x]>deep[y])
		swap(x,y);
	update(id[x],id[y],1,n,1,z);
}
int Q0(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]])
			swap(x,y);
		ans+=q0(id[top[x]],id[x],1,n,1);
		x=fa[top[x]];
	}
	if(deep[x]>deep[y])
		swap(x,y);
	ans+=q0(id[x],id[y],1,n,1);
	return ans;
}
int Q1(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]])
			swap(x,y);
		ans+=q1(id[top[x]],id[x],1,n,1);
		x=fa[top[x]];
	}
	if(deep[x]>deep[y])
		swap(x,y);
	ans+=q1(id[x],id[y],1,n,1);
	return ans;
}
int main()
{
	n=read();
	for(int i=2;i<=n;i++)//从0开始编号
		w[i]=read();
	q=read();
	for(int i=2;i<=n;i++)
	{
		w[i]++;
		addedge(i,w[i]);
		addedge(w[i],i);	
	}
	dfs1(1,0,1);
	cnt=0;
	dfs2(1,1);
	for(int i=1;i<=q;i++)
	{
		int x;
		scanf("%s",ins);
		if(strcmp(ins,"install")==0)
		{
			x=read();
			x++;//从0开始编号 
			printf("%d\n",Q0(1,x));
			uR(1,x,1);
		}
		if(strcmp(ins,"uninstall")==0)
		{
			x=read();
			x++;
			printf("%d\n",q1(id[x],id[x]+siz[x]-1,1,n,1));
			update(id[x],id[x]+siz[x]-1,1,n,1,0);
		}
		for(int i=1;i<=n;i++)
			printf("#%d\n",q0(id[i],id[i],1,n,1));
	} 
	return 0;
}
2020/8/23 10:15
加载中...