蒟蒻刚学树剖求8pts调教
查看原帖
蒟蒻刚学树剖求8pts调教
754467
f_hxr_楼主2023/10/20 09:09

rt

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn=2e5+7;
LL N,M;
struct SegmentTree{
	struct Node{
		Node* ls=nullptr,* rs=nullptr;
		LL Sum,Min=0x3f,Max=-0x3f,oppov;
	}root;
	#define ls(p) p.ls
	#define rs(p) p.rs
	void pushup(Node& p){
		p.Sum=p.ls->Sum+p.rs->Sum;
		p.Max=max(p.ls->Max,p.rs->Max);
		p.Min=min(p.ls->Min,p.rs->Min);
	}
	void pushdown(Node& p){
		if(!ls(p))ls(p)=new Node();
		if(!rs(p))rs(p)=new Node();
		if(p.oppov){
			p.ls->oppov^=p.oppov;p.rs->oppov^=p.oppov;
			p.ls->Sum*=-1;p.rs->Sum*=-1;
			p.ls->Min*=-1;p.rs->Min*=-1;
			p.ls->Max*=-1;p.rs->Max*=-1;
			swap(p.ls->Min,p.ls->Max);
			swap(p.rs->Min,p.rs->Max);
			p.oppov=0;
		}
	}
	void ModifyPoint(Node& p,LL L,LL R,LL inx,LL xx){
		if(L>=R){p.Sum=p.Max=p.Min=xx;return;}
		pushdown(p);
		LL mid=(L+R)>>1;
		if(inx<=mid)ModifyPoint(*ls(p),L,mid,inx,xx);
		else ModifyPoint(*rs(p),mid+1,R,inx,xx);
		pushup(p);
	}
	void ModifyPoint(LL inx,LL xx){ModifyPoint(root,1,N,inx,xx);}
	void ModifyRange(Node& p,LL L,LL R,LL ql,LL qr){
		if(ql<=L&&R<=qr){
			p.Sum*=-1;p.Min*=-1;p.Max*=-1;
			swap(p.Min,p.Max);
			p.oppov^=1;return;
		}
		pushdown(p);LL mid=(L+R)>>1;
		if(ql<=mid)ModifyRange(*ls(p),L,mid,ql,qr);
		if(mid+1<=qr)ModifyRange(*rs(p),mid+1,R,ql,qr);
		pushup(p);
	}
	void ModifyRange(LL ql,LL qr){ModifyRange(root,1,N,ql,qr);}
	LL QueryRangeSum(Node& p,LL L,LL R,LL ql,LL qr){
		if(ql<=L&&R<=qr)return p.Sum;	
		pushdown(p);
		LL mid=(L+R)>>1,ret=0;
		if(ql<=mid)ret+=QueryRangeSum(*ls(p),L,mid,ql,qr);
		if(mid+1<=qr)ret+=QueryRangeSum(*rs(p),mid+1,R,ql,qr);
		return ret;
	}
	LL QueryRangeSum(LL ql,LL qr){return QueryRangeSum(root,1,N,ql,qr);}
	LL QueryRangeMax(Node& p,LL L,LL R,LL ql,LL qr){
		if(ql<=L&&R<=qr)return p.Max;	
		pushdown(p);
		LL mid=(L+R)>>1,ret=-0x3f;
		if(ql<=mid)ret=max(ret,QueryRangeMax(*ls(p),L,mid,ql,qr));
		if(mid+1<=qr)ret=max(ret,QueryRangeMax(*rs(p),mid+1,R,ql,qr));
		return ret;
	}
	LL QueryRangeMax(LL ql,LL qr){return QueryRangeMax(root,1,N,ql,qr);}
	LL QueryRangeMin(Node& p,LL L,LL R,LL ql,LL qr){
		if(ql<=L&&R<=qr)return p.Min;	
		pushdown(p);
		LL mid=(L+R)>>1,ret=0x3f;
		if(ql<=mid)ret=min(ret,QueryRangeMin(*ls(p),L,mid,ql,qr));
		if(mid+1<=qr)ret=min(ret,QueryRangeMin(*rs(p),mid+1,R,ql,qr));
		return ret;
	}
	LL QueryRangeMin(LL ql,LL qr){return QueryRangeMin(root,1,N,ql,qr);}
};
struct SLPF{
	LL head[maxn<<1],nxt[maxn<<1],to[maxn<<1],cnt_edge;
	LL dep[maxn],f[maxn],id[maxn],Hson[maxn],Hd[maxn],size[maxn],dfn;
	LL w[maxn],val[maxn],id_edge[maxn],down[maxn];
	SegmentTree SEG;
	void AddEdge(LL u,LL v,LL _w,LL _id){
		nxt[++cnt_edge]=head[u];to[cnt_edge]=v;
		head[u]=cnt_edge;w[cnt_edge]=_w;id_edge[cnt_edge]=_id;
		nxt[++cnt_edge]=head[v];to[cnt_edge]=u;
		head[v]=cnt_edge;w[cnt_edge]=_w;id_edge[cnt_edge]=_id;
	}
	void dfs1(LL u,LL fa,LL _w,LL _id){
		dep[u]=dep[fa]+1;f[u]=fa;size[u]=1;
		val[u]=_w;down[_id]=u;
		for(int i=head[u];i;i=nxt[i]){
			if(to[i]==fa)continue;
			dfs1(to[i],u,w[i],id_edge[i]);
			size[u]+=size[to[i]];
			if(size[to[i]]>size[Hson[u]])Hson[u]=to[i];
		}
	}
	void dfs2(LL u,LL top){
		id[u]=++dfn;Hd[u]=top;
		if(!Hson[u])return;dfs2(Hson[u],top);
		for(int i=head[u];i;i=nxt[i]){
			if(to[i]==f[u]||to[i]==Hson[u])continue;
			dfs2(to[i],to[i]);
		}
	}
	void init(){
		scanf("%lld",&N);
		for(int i=1;i<N;i++){
			LL a,b,c;scanf("%lld%lld%lld",&a,&b,&c);
			AddEdge(a+1,b+1,c,i);
		}
		dfs1(1,0,0,0);dfs2(1,1);
		for(int i=1;i<=N;i++)SEG.ModifyPoint(id[i],val[id[i]]);
	}
	void ModifyEdgeOnTree(LL e,LL xx){SEG.ModifyPoint(id[down[e]],xx);}
	void ModifyRangeOnTree(LL u,LL v){
		while(Hd[u]!=Hd[v]){
			if(dep[Hd[u]]<dep[Hd[v]])swap(u,v);
			SEG.ModifyRange(id[Hd[u]],id[u]);
			u=f[Hd[u]];
		}
		if(dep[u]<dep[v])swap(u,v);
		if(id[u]!=id[v])SEG.ModifyRange(id[Hson[v]],id[u]);
	}
	LL QuerySumOnTree(LL u,LL v){
		LL ret=0;
		while(Hd[u]!=Hd[v]){
			if(dep[Hd[u]]<dep[Hd[v]])swap(u,v);
			ret+=SEG.QueryRangeSum(id[Hd[u]],id[u]);
			u=f[Hd[u]];
		}
		if(dep[u]<dep[v])swap(u,v);
		if(id[u]!=id[v])ret+=SEG.QueryRangeSum(id[Hson[v]],id[u]);return ret;
	}
	LL QueryMaxOnTree(LL u,LL v){
		LL ret=-0x3f;
		while(Hd[u]!=Hd[v]){
			if(dep[Hd[u]]<dep[Hd[v]])swap(u,v);
			ret=max(ret,SEG.QueryRangeMax(id[Hd[u]],id[u]));
			u=f[Hd[u]];
		}
		if(dep[u]<dep[v])swap(u,v);
		if(id[u]!=id[v])ret=max(ret,SEG.QueryRangeMax(id[Hson[v]],id[u]));return ret;
	}
	LL QueryMinOnTree(LL u,LL v){
		LL ret=0x3f;
		while(Hd[u]!=Hd[v]){
			if(dep[Hd[u]]<dep[Hd[v]])swap(u,v);
			ret=min(ret,SEG.QueryRangeMin(id[Hd[u]],id[u]));
			u=f[Hd[u]];
		}
		if(dep[u]<dep[v])swap(u,v);
		if(id[u]!=id[v])ret=min(ret,SEG.QueryRangeMin(id[Hson[v]],id[u]));return ret;
	}
	void Query(){
		scanf("%lld",&M);
		while(M--){
			char op[6];LL a,b;
			scanf("%s",op);scanf("%lld%lld",&a,&b);
			if(op[0]=='C'){ModifyEdgeOnTree(a,b);}
			else if(op[0]=='N'){ModifyRangeOnTree(a+1,b+1);}
			else if(op[0]=='S'){printf("%lld\n",QuerySumOnTree(a+1,b+1));}
			else if(op[0]=='M'&&op[1]=='A'){printf("%lld\n",QueryMaxOnTree(a+1,b+1));}
			else if(op[0]=='M'&&op[1]=='I'){printf("%lld\n",QueryMinOnTree(a+1,b+1));}
		}
	}
}Tree;
int main(){
	//freopen("P1505_1.in","r",stdin);
	//freopen("P1505_1.ans","w",stdout);
	Tree.init();Tree.Query();
	return 0;
}
2023/10/20 09:09
加载中...