10 pts 一坨 球跳
查看原帖
10 pts 一坨 球跳
926886
kind_Ygg楼主2025/1/13 16:46
#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=1e5+5;
int n;
string op;//操作类型
int l,r,k;//rt
int u[N],v[N],w[N];
struct Edge
{
	int v,w;
};
vector<Edge> edge[N];
int dfn[N],rk[N],fa[N],tot;
int siz[N]/*子树大小*/,son[N]/*重儿子*/;
int top[N];//链头
int deep[N];//深度
int tree[N<<2];
int cover[N<<2],add[N<<2];
void dfs1(int u,int f)
{
	fa[u]=f;//父亲节点
	dfn[u]=++tot;//dfs序
	rk[tot]=u;
	siz[u]=1;//子树大小初始化
	deep[u]=deep[f]+1;//深度
	for(auto i:edge[u])
	{
		int v=i.v;
		if(v!=f)
		{
			dfs1(v,u);
			if(siz[v]>siz[son[u]]) son[u]=v;//更新重儿子
			siz[u]+=siz[v];//更新子树大小
		}
	}
}
void dfs2(int u,int head)//链头
{
	top[u]=head;
	for(auto i:edge[u])
	{
		int v=i.v;
		if(v!=fa[u])
		{
			if(v==son[u])
				dfs2(v,head);
			else
				dfs2(v,v);
		}
	}
}
int ls(int x){return x<<1;}
int rs(int x){return x<<1|1;}
void build(int s,int t,int p)
{
	if(s==t)
	{
		cover[p]=-1;
		return;
	}
	int mid=s+(t-s>>1);
	build(s,mid,ls(p));
	build(mid+1,t,rs(p));
	cover[p]=-1;
}
void push_down(int p)
{
	if(cover[p]!=-1)
	{
		cover[ls(p)]=cover[rs(p)]=cover[p];
		tree[ls(p)]=tree[rs(p)]=cover[p];
		add[ls(p)]=add[rs(p)]=0;
		cover[p]=-1;
	}
	if(add[p])
	{
		add[ls(p)]+=add[p];
		add[rs(p)]+=add[p];
		tree[ls(p)]+=add[p];
		tree[rs(p)]+=add[p];
		add[p]=0;
	}
}
void update(int l,int r,int k,int s,int t,int p)
{
	if(l<=s and t<=r)
	{
		tree[p]+=k;
		add[p]+=k;
		return;
	}
	push_down(p);
	int mid=s+(t-s>>1);
	if(l<=mid) update(l,r,k,s,mid,ls(p));
	if(mid+1<=r) update(l,r,k,mid+1,t,rs(p));
	tree[p]=max(tree[ls(p)],tree[rs(p)]);
}//Add
void Cover(int l,int r,int k,int s,int t,int p)
{
	if(l<=s and t<=r)
	{
		tree[p]=k;
		add[p]=0;
		cover[p]=k;
		return;
	}
	push_down(p);
	int mid=s+(t-s>>1);
	if(l<=mid) Cover(l,r,k,s,mid,ls(p));
	if(mid+1<=r) Cover(l,r,k,mid+1,t,rs(p));
	tree[p]=max(tree[ls(p)],tree[rs(p)]);
}//Cover and Change
int query(int l,int r,int s,int t,int p)
{
	if(l<=s and t<=r) return tree[p];
	int ans=LLONG_MIN;
	push_down(p);
	int mid=s+(t-s>>1);
	if(l<=mid) ans=query(l,r,s,mid,ls(p));
	if(mid+1<=r) ans=max(ans,query(l,r,mid+1,t,rs(p)));
	return ans;
}//Max
void Cover_on_tree(int x,int y,int k)
{
	while(top[x]!=top[y])
	{
		if(deep[top[x]]>deep[top[y]]) swap(x,y);
		Cover(rk[top[y]],rk[y],k,1,n,1);
		y=fa[top[y]];
	}
	if(x!=y)
	{
		if(deep[x]>deep[y]) swap(x,y);
		Cover(rk[son[x]],rk[y],k,1,n,1);
	}
}
void update_on_tree(int x,int y,int k)
{
	while(top[x]!=top[y])
	{
		if(deep[top[x]]>deep[top[y]]) swap(x,y);
		update(rk[top[y]],rk[y],k,1,n,1);
		y=fa[top[y]];
	}
	if(x!=y)
	{
		if(deep[x]>deep[y]) swap(x,y);
		update(rk[son[x]],rk[y],k,1,n,1);
	}
}
int query_on_tree(int x,int y)
{
	int ans=LLONG_MIN;
	while(top[x]!=top[y])
	{
		if(deep[top[x]]>deep[top[y]]) swap(x,y);
		ans=max(ans,query(rk[top[y]],rk[y],1,n,1));
		y=fa[top[y]];
	}
	if(x!=y)
	{
		if(deep[x]>deep[y]) swap(x,y);
		ans=max(ans,query(rk[son[x]],rk[y],1,n,1));
	}
	return ans;
}
signed main()
{
	freopen("P4315_1.in","r",stdin);
	freopen("P4315.out","w",stdout);
	cin>>n;
	for(int i=1;i<n;i++)
	{
		cin>>u[i]>>v[i]>>w[i];
		edge[u[i]].push_back((Edge){v[i],w[i]});
		edge[v[i]].push_back((Edge){u[i],w[i]});
	}
	dfs1(1,1);
	dfs2(1,1);
	build(1,n,1);
	for(int i=1;i<n;i++)
	{
		if(fa[u[i]]==v[i])
			swap(u[i],v[i]);
		Cover(rk[v[i]],rk[v[i]],w[i],1,n,1);
	}
	while(op!="Stop")
	{
		cin>>op;
		if(op=="Change")
		{
			cin>>l>>k;
			Cover(rk[v[l]],rk[v[l]],k,1,n,1);
		}
		else if(op=="Cover")
		{
			cin>>l>>r>>k;
			Cover_on_tree(l,r,k);
		}
		else if(op=="Add")
		{
			cin>>l>>r>>k;
			update_on_tree(l,r,k);
		}
		else if(op=="Max")
		{
			cin>>l>>r;
			cout<<query_on_tree(l,r)<<'\n';
		}
	}
	return 0;
}

下数据点看是 Max 函数错了

2025/1/13 16:46
加载中...