萌新刚学数剖,只通过了两个点,求助
查看原帖
萌新刚学数剖,只通过了两个点,求助
483252
罗小菜楼主2022/7/12 20:48

RT

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
#define int long long
const int MAXN=1e5+10;
int tree[MAXN*8],tag[MAXN*8];
bool have_tag[MAXN*8];
int sz[MAXN],son[MAXN],idx[MAXN];
int fa[MAXN],topfa[MAXN],deep[MAXN];
bool used[MAXN];
int f[MAXN][30];
int tot;
int n,m;
int root;
vector<int> g[MAXN];
inline void push_down(int rt,int l,int r)
{
	if(not have_tag[rt]) return ;
	tree[rt]=tag[rt];
	tag[rt*2]=tag[rt];
	tag[rt*2+1]=tag[rt];
	tag[rt]=0;
	have_tag[rt*2]=true;
	have_tag[rt*2+1]=true;
	have_tag[rt]=false;
	return ;
}
inline void push_up(int rt,int l,int r)
{
	int mid=(l+r)/2;
	push_down(rt,l,r);
	push_down(rt*2,l,mid);
	push_down(rt*2+1,mid+1,r);
	tree[rt]=min(tree[rt*2],tree[rt*2+1]);
	return ;
}
void update(int rt,int l,int r,int L,int R,int x)
{
	push_down(rt,l,r);
	if(L<=l && r<=R)
	{
		tag[rt]=x;
		have_tag[rt]=true;
		return ;
	}
	int mid=(l+r)/2;
	if(L<=mid) update(rt*2,l,mid,L,R,x);
	if(R>mid) update(rt*2+1,mid+1,r,L,R,x);
	push_up(rt,l,r);
	return ;
}
int query(int rt,int l,int r,int L,int R)
{
	push_down(rt,l,r);
	if(L<=l && r<=R) return tree[rt];
	int mid=(l+r)/2;
	int res=1e9;
	if(L<=mid) res=min(res,query(rt*2,l,mid,L,R));
	if(R>mid) res=min(res,query(rt*2+1,mid+1,r,L,R));
	return res;
}
void DFS1(int now,int lst,int depth)
{
	deep[now]=depth;
	fa[now]=lst;
	sz[now]=1;
	f[now][0]=lst;
	for(int i=1;i<=20;i++) f[now][i]=f[f[now][i-1]][i-1];
	for(int i=0;i<g[now].size();i++)
	{
		int v=g[now][i];
		if(v==lst) continue;
		DFS1(v,now,depth+1);
		sz[now]+=sz[v];
		if(sz[v]>sz[son[now]]) son[now]=v;
	}
	return ;
}
void DFS2(int now,int lst,int top)
{
	if(now==0) return ;
	topfa[now]=top;
	idx[now]=++tot;
	used[now]=true;
	DFS2(son[now],now,top);
	for(int i=0;i<g[now].size();i++)
	{
		int v=g[now][i];
		if(v==lst || used[v]) continue;
		DFS2(v,now,v);
	}
	return ;
}
inline int LCA(int x,int y)
{
	while(topfa[x]!=topfa[y])
	{
		int fax=topfa[x],fay=topfa[y];
		if(deep[fay]>deep[fax])
		{
			swap(fax,fay);
			swap(x,y);
		}
		x=fa[fax];
	}
	if(deep[y]>deep[x]) swap(x,y);
	return y;
}
inline int New_son(int x)
{
	int y=root;
	for(int i=20;i>=0;i--) if(deep[y]-(1<<i)>deep[x]) y=f[y][i];
	return y;
}
inline void update_range(int x,int y,int z)
{
	while(topfa[x]!=topfa[y])
	{
		int fax=topfa[x],fay=topfa[y];
		if(deep[fay]>deep[fax])
		{
			swap(fax,fay);
			swap(x,y);
		}
		update(1,1,n,idx[fax],idx[x],z);
		x=fa[fax];
	}
	if(deep[y]>deep[x]) swap(x,y);
	update(1,1,n,idx[y],idx[x],z);
	return ;
}
inline int query_New_root(int x)
{
	if(x==root) return query(1,1,n,1,n);
	int l=LCA(x,root);
	if(l==x)
	{
		int s=New_son(x);
		return min(query(1,1,n,1,idx[s]-1),query(1,1,n,idx[s]+sz[x],n));
	}
	else return query(1,1,n,idx[x],idx[x]+sz[x]-1);
}
signed main()
{
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);
	cin>>n>>m;
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	DFS1(1,0,1);
	DFS2(1,0,1);
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		update(1,1,n,idx[i],idx[i],x);
	}
	cin>>root;
	for(int i=1;i<=m;i++)
	{
		int op;
		cin>>op;
		if(op==1)
		{
			int x;
			cin>>x;
			root=x;
		}
		if(op==2)
		{
			int x,y,z;
			cin>>x>>y>>z;
			update_range(x,y,z);
		}
		if(op==3)
		{
			int x;
			cin>>x;
			cout<<query_New_root(x)<<"\n";
		}
	}
	return 0;
}
2022/7/12 20:48
加载中...