8pts 树剖求调qwqz
查看原帖
8pts 树剖求调qwqz
378706
MoyunAllgorithm楼主2023/6/8 19:14
#include<bits/stdc++.h>
#define PII pair<int,int>
#define lson pos<<1
#define rson pos<<1|1
using namespace std;
const int MAXN=2e5+5;
int N,Q;
int dep[MAXN],f[MAXN],son[MAXN],siz[MAXN],tp[MAXN],dfn[MAXN];
int ori[MAXN],val[MAXN];
PII e[MAXN];
int tim=0;
vector<PII>gra[MAXN];
struct SegTree
{
	int mn,mx,sum,tag;
}tre[MAXN<<2];
void PushUp(int pos)
{
	tre[pos].mn=min(tre[lson].mn,tre[rson].mn);
	tre[pos].mx=max(tre[lson].mx,tre[rson].mx);
	tre[pos].sum=tre[lson].sum+tre[rson].sum;
}
void Build(int pos,int l,int r)
{
	if(l==r)
	{
		tre[pos]={val[l],val[l],val[l],1};
		return;
	}
	int mid=(l+r)>>1;
	Build(lson,l,mid);
	Build(rson,mid+1,r);
	PushUp(pos);
	return;
}
void PushDown(int pos,int l,int r)
{
	if(l==r) return;
	if(tre[pos].tag==-1)
	{
		tre[lson].tag=-tre[lson].tag;
		tre[lson].sum=-tre[lson].sum;
		tre[lson].mx=-tre[lson].mx;
		tre[lson].mn=-tre[lson].mn;
		swap(tre[lson].mx,tre[lson].mn);
		tre[rson].tag=-tre[rson].tag;
		tre[rson].sum=-tre[rson].sum;
		tre[rson].mx=-tre[rson].mx;
		tre[rson].mn=-tre[rson].mn;
		swap(tre[rson].mx,tre[rson].mn);
	}
	tre[pos].tag=1;
	return;
}
void Update(int pos,int l,int r,int q,int x)
{
	PushDown(pos,l,r);
	if(l==r)
	{
		tre[pos].mn=tre[pos].mx=tre[pos].sum=x;
		return;
	}
	
	int mid=(l+r)>>1;
	if(q<=mid) Update(lson,l,mid,q,x);
    else Update(rson,mid+1,r,q,x);
    PushUp(pos);
	return;
}
void Reverse(int pos,int l,int r,int ql,int qr)
{
	PushDown(pos,l,r);
	if(ql<=l&&r<=qr)
	{
		tre[pos].tag=-tre[pos].tag;
		tre[pos].sum=-tre[pos].sum;
		tre[pos].mx=-tre[pos].mx;
		tre[pos].mn=-tre[pos].mn;
		swap(tre[pos].mx,tre[pos].mn);
		return;
	}
	
	int mid=(l+r)>>1;
	if(ql<=mid) Reverse(lson,l,mid,ql,qr);
	if(mid<qr) Reverse(rson,mid+1,r,ql,qr);
	PushUp(pos);
	return;
}
int QueryMin(int pos,int l,int r,int ql,int qr)
{
	PushDown(pos,l,r);
	if(ql<=l&&r<=qr) 
	{
		return tre[pos].mn;
	}
	int res=2e9;
	int mid=(l+r)>>1;
	if(ql<=mid) res=min(res,QueryMin(lson,l,mid,ql,qr));
	if(mid<qr) res=min(res,QueryMin(rson,mid+1,r,ql,qr));
//	PushUp(pos);
	return res;
}
int QueryPathMin(int u,int v)
{
	int res=2e9;
	while(tp[u]!=tp[v])
	{
		if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
		res=min(res,QueryMin(1,1,N,dfn[tp[v]],dfn[v]));
		v=f[tp[v]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	if(dfn[u]+1<=dfn[v]) res=min(res,QueryMin(1,1,N,dfn[u]+1,dfn[v]));
	return res;
}
int QueryMax(int pos,int l,int r,int ql,int qr)
{
	PushDown(pos,l,r);
	if(ql<=l&&r<=qr) 
	{
		return tre[pos].mx;
	}
	int res=-2e9;
	int mid=(l+r)>>1;
	if(ql<=mid) res=max(res,QueryMax(lson,l,mid,ql,qr));
	if(mid<qr) res=max(res,QueryMax(rson,mid+1,r,ql,qr));
//	PushUp(pos);
	return res;
}
int QueryPathMax(int u,int v)
{
	int res=-2e9;
	while(tp[u]!=tp[v])
	{
		if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
		res=max(res,QueryMax(1,1,N,dfn[tp[v]],dfn[v]));
		v=f[tp[v]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	if(dfn[u]+1<=dfn[v]) res=max(res,QueryMax(1,1,N,dfn[u]+1,dfn[v]));
	return res;
}
int QuerySum(int pos,int l,int r,int ql,int qr)
{
	PushDown(pos,l,r);
	if(ql<=l&&r<=qr) 
	{
		return tre[pos].sum;
	}
	int res=0;
	int mid=(l+r)>>1;
	if(ql<=mid) res+=QuerySum(lson,l,mid,ql,qr);
	if(mid<qr) res+=QuerySum(rson,mid+1,r,ql,qr);
//	PushUp(pos);
	return res;
}
int QueryPathSum(int u,int v)
{
	int res=0;
	while(tp[u]!=tp[v])
	{
		if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
		res+=QuerySum(1,1,N,dfn[tp[v]],dfn[v]);
		v=f[tp[v]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	if(dfn[u]+1<=dfn[v]) res+=QuerySum(1,1,N,dfn[u]+1,dfn[v]);
	return res;
}
void PathReverse(int u,int v)
{
	while(tp[u]!=tp[v])
	{
		if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
		Reverse(1,1,N,dfn[tp[v]],dfn[v]);
		v=f[tp[v]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	if(dfn[u]+1<=dfn[v]) Reverse(1,1,N,dfn[u]+1,dfn[v]);
	return;
}
void dfs1(int u,int fa)
{
//	printf("DFS1:%d %d\n",u,fa);
	dep[u]=dep[fa]+1;
	siz[u]=1;
	f[u]=fa;
	for(auto [v,w]:gra[u])
	{
		if(v==fa) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		ori[v]=w;
		if(siz[v]>siz[son[u]]) son[u]=v;
	}
	return;
}
void dfs2(int u,int rt)
{
//	printf("DFS2:%d %d\n",u,rt);
	tp[u]=rt;
	dfn[u]=++tim;
	val[tim]=ori[u];
	if(son[u]) dfs2(son[u],rt);
	for(auto [v,w]:gra[u])
	{
		if(v!=f[u]&&v!=son[u]) dfs2(v,v);
	}
	return;
}
int main()
{
	scanf("%d",&N);
	for(int i=1;i<N;i++)
	{
		int u,v,w;
		scanf("%d %d %d",&u,&v,&w);
		u++,v++;
		gra[u].push_back({v,w});
		gra[v].push_back({u,w});
		e[i]={u,v};
	}
	dfs1(1,0);
	dfs2(1,1);
	Build(1,1,N);
	int ind=0;
	scanf("%d",&Q);
	while(Q--)
	{
		char s[10];
		scanf("%s",s+1);
		int u,v;
		scanf("%d %d",&u,&v);
		if(s[1]=='C')
		{
			int x=e[u].first,y=e[u].second;
			if(dep[x]>dep[y]) swap(x,y);
			Update(1,1,N,dfn[y],v);
		}
		if(s[1]=='N')
		{
			u++,v++;
			PathReverse(u,v);
		}
		if(s[1]=='S')
		{
			u++,v++;
			printf("%d\n",QueryPathSum(u,v));
		}
		if(s[1]=='M'&&s[2]=='A')
		{
			u++,v++;
			printf("%d\n",QueryPathMax(u,v));
		}
		if(s[1]=='M'&&s[2]=='I')
		{
			u++,v++;
			printf("%d\n",QueryPathMin(u,v));
		}
	}
	return 0;
}
2023/6/8 19:14
加载中...