ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C20220712T3 牛半仙的妹子Tree

2022-08-30 16:32:38  阅读:71  来源: 互联网

标签:半仙 minn ll Tree pos C20220712T3 100005 fa stabf


给定一棵树,要求执行3种操作:

  1. 给树上某一结点涂色,从下一次操作起每一次向周围传染一个单位。
  2. 树上所有点变为正常
  3. 询问某个点是否被感染。

\(n,m\leq 10^5\)。


首先想到暴力做法,用栈维护现在被感染的节点以及感染时间,那么对于操作1,2都好解决,对于操作3需要遍历栈并求出是否有节点可以传染到它(即 \(dis(u,v)\leq time\_now-time\_u\) )。实测可以拿40。

考虑优化思路,可以发现这题的瓶颈在于栈中点太多,那么可以考虑当栈中点过多时可以直接 \(dfs\) 一边,将答案记录在节点上,然后清空,保证对于之前的点可以 \(O(1)\) 查询,同时若出现操作2就直接打上标记,表示之前的点被清空。对于大块整体处理,小块暴力,就是一个类似分块的做法。

struct edge{
	ll to,nxt;
}e[200005];

struct node{
	ll pos,t;
	node(ll x,ll y){
		pos=x;
		t=y;
	}
	node(){pos=0;t=0;}
}stabf[100005],sta[100005];

ll head[100005],ecnt;

void adde(ll u,ll v){
	e[++ecnt].nxt=head[u];
	e[ecnt].to=v;
	head[u]=ecnt;
}
std::queue<node> q;
ll n,m,flag,fa[100005][20],dep[100005],minn[100005],vis[100005];//17
ll top=-1,bj,block,topbf=-1;


void dfs(ll x){
	dep[x]=dep[fa[x][0]]+1;
	FOR(i,1,17){
		fa[x][i]=fa[fa[x][i-1]][i-1];
	}
	for(rg ll i=head[x];i;i=e[i].nxt){
		ll y=e[i].to;
		if(y==fa[x][0])
			continue;
		fa[y][0]=x;
		dfs(y);
	}
}

void bfs(){
	while(q.size())
		q.pop();
	memset(minn,0x3f,sizeof(minn));
	memset(vis,0,sizeof(vis));
	FOR(i,0,top){
		stabf[++topbf]=sta[i];
	}
	FOR(i,0,topbf){
		minn[stabf[i].pos]=std::min(minn[stabf[i].pos],stabf[i].t);
	}
	q.push(stabf[0]);
	ll rr=1;
	while(q.size()){
		node u=q.front();
		q.pop();
		for(rg ll i=head[u.pos];i;i=e[i].nxt){
			int v=e[i].to;
			if(vis[v]==0){
				vis[v]=1;
				minn[v]=std::min(minn[v],minn[u.pos]+1);
				q.push(node(v,minn[v]));
				if(minn[v]==stabf[rr].t){
					vis[stabf[rr].pos]=1;
					q.push(stabf[rr]);
					++rr;
				}
			}
		}
	}
}

ll dis(ll x,ll y){
	ll ret=0;
	if(dep[x]<dep[y])
		std::swap(x,y);
	ROF(i,17,0){
		if(dep[fa[x][i]]>=dep[y]){
			ret+=1<<i;
			x=fa[x][i];
		}
	}
	ROF(i,17,0){
		if(fa[x][i]!=fa[y][i]){
			ret+=1<<(1+i);
			x=fa[x][i];
			y=fa[y][i];
		}
	}
	if(x!=y)
		ret+=2;
	return ret;
}



int main(){
	memset(minn,0x3f,sizeof(minn));
	n=in(),m=in();
	block=900;
	FOR(i,1,n-1){
		ll u=in(),v=in();
		adde(u,v);
		adde(v,u);
	}
	dfs(1);
	FOR(z,1,m){
		if(z%block==0){
			bfs();
			top=-1;
			bj=0;
		}
		ll op=in(),x=in();
		if(op==1){
			sta[++top]=node(x,z);
		}
		if(op==2){
			top=-1;
			topbf=-1;
			bj=1;
		}
		if(op==3){
			ll flag=0;
			FOR(i,0,top){
				if(dis(sta[i].pos,x)<=(z-sta[i].t)){
					puts("wrxcsd");
					flag=1;
					break;
				}
			}
			if(bj==0 && flag==0){
				if(minn[x]<=z){
					puts("wrxcsd");
					continue;
				}
			}
			if(flag==0){
				puts("orzFsYo");
			}
		}
	}
	return 0;
} 

标签:半仙,minn,ll,Tree,pos,C20220712T3,100005,fa,stabf
来源: https://www.cnblogs.com/zhouzizhe/p/16639832.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有