求助,为什么点从0开始存会超时,改成从1开始存就秒过
查看原帖
求助,为什么点从0开始存会超时,改成从1开始存就秒过
118027
Pokemon_song楼主2021/1/28 16:54
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>

using namespace std;
vector<int> e[200010];
int n,q,mxx;
int sum,v[800010],lan[800010],a[100010];
int dfn[100010],cnt,sz[100010],F[100010],R[100010],d[100010],son[100010],top[100010];
void dfs1(int k,int fa)
{
	sz[k]=1;
	int len=e[k].size();
	for(int i=0;i<len;i++)
		if(e[k][i]!=fa)
		{
			d[e[k][i]]=d[k]+1;
			F[e[k][i]]=k;
			dfs1(e[k][i],k);
			if(sz[e[k][i]]>sz[son[k]]) son[k]=e[k][i];
			sz[k]+=sz[e[k][i]];
		}
}
void dfs2(int k,int fa)
{
	dfn[k]=++cnt;
	if(son[k]) 
	{
		top[son[k]]=top[k];
		dfs2(son[k],k);
	}
	int len=e[k].size();
	for(int i=0;i<len;i++)
		if(e[k][i]!=fa && e[k][i]!=son[k])
			{
			top[e[k][i]]=e[k][i];
			dfs2(e[k][i],k);
			}
	R[k]=cnt;
}
void pushdown(int root,int l,int r,int mid)
{
	lan[root<<1]=lan[root<<1|1]=lan[root];
	v[root<<1]=(mid-l+1)*lan[root];
	v[root<<1|1]=(r-mid)*lan[root];
	lan[root]=-1;
}
void tag(int root,int l,int r,int s,int t,int V)
{
	if(s<=l && r<=t)
	{
		v[root]=V*(r-l+1);
		lan[root]=V;
		return;
	}
	int mid=(l+r)/2;
	if(lan[root]!=-1) pushdown(root,l,r,mid);
	if(s<=mid) tag(root<<1,l,mid,s,t,V);
	if(t>mid) tag(root<<1|1,mid+1,r,s,t,V);
	v[root]=v[root<<1]+v[root<<1|1];
}
int query(int root,int l,int r,int s,int t)
{
	if(s<=l && r<=t)
	{
		return v[root];
	}
	int mid=(l+r)/2;
	if(lan[root]!=-1) pushdown(root,l,r,mid);
	int num=0;
	if(s<=mid) num+=query(root<<1,l,mid,s,t);
	if(t>mid) num+=query(root<<1|1,mid+1,r,s,t);
	return num;
}
void install(int x)
{
	sum=d[x]+1;
	while(top[x])
	{
		sum-=query(1,1,n,dfn[top[x]],dfn[x]);
		tag(1,1,n,dfn[top[x]],dfn[x],1);
		x=F[top[x]];
	}
	sum-=query(1,1,n,dfn[0],dfn[x]);
	tag(1,1,n,dfn[0],dfn[x],1);
}
void uninstall(int x)
{
	sum=query(1,1,n,dfn[x],R[x]);
	tag(1,1,n,dfn[x],R[x],0);
}
int main()
{
	scanf("%d",&n);
	memset(lan,-1,sizeof(lan));
	for(int i=1;i<n;i++)
		{
		int x;
		scanf("%d",&x);
		e[x].push_back(i);
		}
	dfs1(0,-1);
	top[0]=0;
	dfs2(0,-1);
	scanf("%d",&q);
	while(q--)
	{
		char f[15];
		scanf("%s",f);
		if(f[0]=='i')
		{
			int x;
			scanf("%d\n",&x);
			//x++;
			install(x);
			printf("%d\n",sum);
		}
 		else
		{
			int x;
			scanf("%d\n",&x);
			//x++;
			uninstall(x);
			printf("%d\n",sum);
		}
	}

	return 0;
}

2021/1/28 16:54
加载中...