4.3KB屎山0pts求条
查看原帖
4.3KB屎山0pts求条
1058570
tzhengqing楼主2025/1/13 15:25

rt,3-71行是线段树,72-151行是树剖。

#include<bits/stdc++.h>
using namespace std;
#define Puck 1000005
#define puck -2e9
int n,a[Puck],tree[Puck<<2],tag[Puck<<2],tag2[Puck<<2];
inline int ls(int p){return p<<1;}
inline int rs(int p){return p<<1|1;}
void add_up(int p){tree[p]=max(tree[ls(p)],tree[rs(p)]);}						//上传区间值 
void build(int p,int pl,int pr)												//p代表区间[pl,pr] 
	{
	tag[p]=0;tag2[p]=puck;if(pl==pr){tree[p]=a[pl];return;}								//叶子节点赋值
	int mid=(pl+pr)>>1;
	build(ls(p),pl,mid);build(rs(p),mid+1,pr); 
	add_up(p);
	}
void add_tag(int p,int pl,int pr,int d)										//懒一下 
	{
	if(tag2[p]!=puck)tag2[p]+=d;
	else tag[p]+=d;
	tree[p]+=d;
	} 
void gai_tag(int p,int pl,int pr,int d)
	{
	tag[p]=0;tag2[p]=tree[p]=d;
	}
void add_down(int p,int pl,int pr)											//懒重叠处理 
	{
	if(tag2[p]!=puck)
		{
		int mid=(pl+pr)>>1;
		gai_tag(ls(p),pl,mid,tag2[p]);gai_tag(rs(p),mid+1,pr,tag2[p]);
		tag2[p]=puck;
		}
	else if(tag[p])
		{
		int mid=(pl+pr)>>1;
		add_tag(ls(p),pl,mid,tag[p]);										//下传处理 
		add_tag(rs(p),mid+1,pr,tag[p]);
		tag[p]=0;
		}
	}
void add(int l,int r,int p,int pl,int pr,int d)								//修改 
	{
	if(l>r)return;
	if(l<=pl&&pr<=r){add_tag(p,pl,pr,d);return;}							//正好不用处理重叠 
	add_down(p,pl,pr);														//重叠处理 
	int mid=(pl+pr)>>1;
	if(l<=mid)add(l,r,ls(p),pl,mid,d);										 
	if(r>mid)add(l,r,rs(p),mid+1,pr,d);
	add_up(p);
	}
void gai(int l,int r,int p,int pl,int pr,int d)
	{
	if(l>r)return;
	if(l<=pl&&pr<=r){gai_tag(p,pl,pr,d);return;}
	add_down(p,pl,pr);
	int mid=(pl+pr)>>1;
	if(l<=mid)gai(l,r,ls(p),pl,mid,d);
	if(r>mid)gai(l,r,rs(p),mid+1,pr,d);
	add_up(p);
	}
int query(int l,int r,int p,int pl,int pr)
	{
	if(l>r)return -114514;
	if(l<=pl&&pr<=r)return tree[p];
	add_down(p,pl,pr);
	int ans=-1e9,mid=(pl+pr)>>1;
	if(l<=mid)ans=max(ans,query(l,r,ls(p),pl,mid));
	if(r>mid)ans=max(ans,query(l,r,rs(p),mid+1,pr));
	return ans;
	}
int fa[Puck],dep[Puck],siz[Puck],son[Puck],top[Puck],dfn[Puck],pos[Puck],cnt=0;
vector<int>e[Puck];
vector<pair<int,int> >e2[Puck];
void dfs0(int u,int f)
	{
	for(int i=0;i<e2[u].size();i++)
		{
		pair<int,int> v=e2[u][i];
		int x=v.first,d=v.second;
		if(x==f)continue;
		a[x]=d;dfs0(x,u);
		}
	}
void dfs1(int u,int f)
	{
	fa[u]=f;siz[u]=1;son[u]=0;dep[u]=dep[f]+1;
	for(int i=0;i<e[u].size();i++)
		{
		int v=e[u][i];
		if(v==f)continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]])son[u]=v;
		}
	}
void dfs2(int u,int tp)
	{
	top[u]=tp;dfn[u]=++cnt;pos[cnt]=u;
	if(son[u])dfs2(son[u],tp);
	for(int i=0;i<e[u].size();i++)
		{
		int v=e[u][i];
		if(v==fa[u]||v==son[u])continue;
		dfs2(v,v);
		}
	}
void upd1(int x,int y,int d)
	{
	while(top[x]!=top[y])
		{
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		int dd=top[x];
		int xx=dfn[dd],yy=dfn[x];
		gai(xx,yy,1,1,n,d);
		x=fa[top[x]];
		}
	if(x==y)return;
	if(dep[x]>dep[y])swap(x,y);
	gai(dfn[son[x]],dfn[y],1,1,n,d);
	}
void upd2(int x,int y,int d)
	{
	while(top[x]!=top[y])
		{
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		int dd=top[x];
		int xx=dfn[dd],yy=dfn[x];
		add(xx,yy,1,1,n,d);
		x=fa[top[x]];
		}
	if(x==y)return;
	if(dep[x]>dep[y])swap(x,y);
	add(dfn[son[x]],dfn[y],1,1,n,d);
	}
int query1(int x,int y)
	{
	int ans=-114514;
	while(top[x]!=top[y])
		{
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		int dd=top[x];
		int xx=dfn[dd],yy=dfn[x];
		ans=max(ans,query(xx,yy,1,1,n));
		x=fa[top[x]];
		}
	if(x==y)return ans;
	if(dep[x]>dep[y])swap(x,y);
	ans=max(ans,query(dfn[son[x]],dfn[y],1,1,n));
	return ans;
	}
int q[Puck][2];
signed main()
	{
	//freopen("P4315_1.in","r",stdin);
	//freopen("P4315.out","w",stdout);
	cin>>n;
	for(int i=1;i<n;i++)
		{
		int x,y,d;cin>>x>>y>>d;
		e[x].push_back(y);e2[x].push_back({y,d});
		e[y].push_back(x);e2[y].push_back({x,d});
		q[i][0]=x;q[i][1]=y;
		}
	dfs0(1,1);
	build(1,1,n);
	dfs1(1,1);
	dfs2(1,1);
	while(1)
		{
		string s;cin>>s;
		if(s=="Stop")return 0;
		if(s=="Cover"){int x,y,d;cin>>x>>y>>d;upd1(x,y,d);}
		if(s=="Add"){int x,y,d;cin>>x>>y>>d;upd2(x,y,d);}
		if(s=="Change")
			{
			int x,d;cin>>x>>d;int qu;
			if(dep[q[x][0]]<dep[q[x][1]])qu=q[x][1];
			else qu=q[x][0];
			gai(dfn[qu],dfn[qu],1,1,n,d);
			}
		if(s=="Max"){int x,y;cin>>x>>y;cout<<query1(x,y)<<'\n';}
		}
	return 0;
	}
2025/1/13 15:25
加载中...