50pts 求调
查看原帖
50pts 求调
231543
bloodstalk楼主2023/2/4 14:52

RT,一上午了,思路就是主流思路。

#include<bits/stdc++.h>
#define int long long
#define ll long long
#define next nxt
#define re register
#define il inline
const int N = 1e6 + 5;
const int M = 1e6 + 5;	
const int INF = 1e18;
using namespace std;
int max(int x,int y){return x > y ? x : y;}
int min(int x,int y){return x < y ? x : y;}

struct node{
	int u,v,next;
}edge[M<<1]; int head[N],num_edge;
int w[N],wt[N];
int n,m,u,v,x,y,k,op,root;
int tree[N<<2],tag[N<<2];
int son[N],id[N],fa[N][23],tot,dep[N],siz[N],top[N];

il int read()
{
	int f=0,s=0;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) f |= (ch=='-');
	for(; isdigit(ch);ch=getchar()) s = (s<<1) + (s<<3) + (ch^48);
	return f ? -s : s;
}

il void add(int from,int to)
{
	edge[++num_edge] = (node){from,to,head[from]};
	head[from] = num_edge;
}

#define lc p<<1
#define rc p<<1|1

il void build(int p,int l,int r)
{
	if(l == r)
	{
		tree[p] = wt[l];
		return ;
	}
	int mid = (l+r) >> 1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	tree[p] = min(tree[lc],tree[rc]);
}

il void push_down(int p)
{
	tag[lc] = tag[rc] = tag[p];
	tree[lc] = tree[rc] = tag[p];
	tag[p] = 0;
}

il void Modify(int nl,int nr,int l,int r,int p,int k)
{
	if(l >= nl && r <= nr)
	{
		tag[p] = tree[p] = k;
		return ;
	}
	if(tag[p]) push_down(p);
	int mid = (l+r) >> 1;
	if(nl <= mid) Modify(nl,nr,l,mid,lc,k);
	if(nr > mid) Modify(nl,nr,mid+1,r,rc,k);
	tree[p] = min(tree[lc],tree[rc]);
}

il int Query(int nl,int nr,int l,int r,int p)
{
	int res = INF;
	if(l >= nl && r <= nr) return tree[p];
	if(tag[p]) push_down(p);
	int mid = (l+r) >> 1;
	if(nl <= mid) res = min(res,Query(nl,nr,l,mid,lc));
	if(nr > mid) res = min(res,Query(nl,nr,mid+1,r,rc));
	return res;
}

/*------------------------------------------*/

il void dfs1(int x,int f)
{
	dep[x] = dep[f] + 1 , fa[x][0] = f , siz[x] = 1;
	for(re int i=head[x];i;i=edge[i].next)
	{
		int y = edge[i].v;
		if(y == f) continue;
		dfs1(y,x);
		siz[x] += siz[y];
		if(siz[son[x]] < siz[y]) son[x] = y;
	}
}

il void dfs2(int x,int topf)
{
	id[x] = ++tot , wt[tot] = w[x] , top[x] = topf;
	if(!son[x]) return ;
	dfs2(son[x],topf);
	for(re int i=head[x];i;i=edge[i].next)
	{
		int y = edge[i].v;
		if(y == fa[x][0] || y == son[x]) continue;
		dfs2(y,y);
	}
}

il void init()
{
	for(re int j=1;j<=22;j++)
		for(re int i=1;i<=n;i++)
			fa[i][j] = fa[fa[i][j-1]][j-1];
}

il int LCA(int x,int y)
{
	while(top[x] != top[y])
	{
		if(dep[top[x]] < dep[top[y]]) swap(x,y);
		x = fa[top[x]][0];
	}
	return dep[x] < dep[y] ? x : y;
}

il void Modify_way(int x,int y,int k)
{
	while(top[x] != top[y])
	{
		if(dep[top[x]] < dep[top[y]]) swap(x,y);
		Modify(id[top[x]],id[x],1,n,1,k);
		x = fa[top[x]][0];
	}
	if(dep[x] > dep[y]) swap(x,y);
	Modify(id[x],id[y],1,n,1,k);
}

il int jump(int x,int depth)
{
	for(re int i=22;i>=0;i--) if(dep[fa[x][i]] >= depth) x = fa[x][i];
	return x;
}

il void Query_way(int x)
{
	if(x == root) { cout << tree[1] << "\n"; return ; }
	int lca = LCA(x,root);
	if(lca == x)
	{
		int y = jump(root,dep[root]-dep[x]-1);
		int p=INF,q=INF;
		if(id[y]-1 >= 1) p = Query(1,id[y]-1,1,n,1);
		if(id[y]+siz[y] <= n) q = Query(id[y]+siz[y],n,1,n,1);
		cout << min(p,q) << "\n"; 
	}
	else cout << Query(id[x],id[x]+siz[x]-1,1,n,1) << "\n";
}

signed main()
{
	n = read() , m = read();
	for(re int i=1;i<=n-1;i++)
	{
		u = read() , v = read();
		add(u,v) , add(v,u);
	}
	for(re int i=1;i<=n;i++) w[i] = read();
	root = read();
	dfs1(1,0);
	dfs2(1,1);
	init();
	build(1,1,n);
	for(re int i=1;i<=m;i++)
	{
		op = read();
		if(op == 1) root = read();
		if(op == 2) x=read(),y=read(),k=read(),Modify_way(x,y,k);
		if(op == 3) x=read() , Query_way(x);
	}
	return 0;
}
2023/2/4 14:52
加载中...