0pts求调,悬赏一关注
查看原帖
0pts求调,悬赏一关注
635829
D_FANG楼主2023/7/31 12:18
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,a[200010],b[200010];
int en,fi[200020];



struct rec{
	int e,nex,d,i;
}z[400010];
void addb(int s,int e,int d){
	en++;
	z[en].e=e;
	z[en].d=d;
	z[en].nex=fi[s];
	fi[s]=en;
}



int fa[200010],son[200010],siz[200010],deep[200010],top[200010],id[200010],id1[400010];
void dfs1(int x,int f,int de){
	fa[x]=f;
	siz[x]=1;
	deep[x]=de;
	int p=-1;
	for (int j=fi[x];j!=0;j=z[j].nex){
		int i=z[j].e;
		if (deep[i]==0){
			dfs1(i,x,de+1);
			siz[x]+=siz[i];
			b[i]=z[j].d;
			id1[z[j].i]=i;
			if (p==-1||siz[p]<siz[i]){
				p=i;
			}
		}
	}
	son[x]=p;
	return ;
}
int cnt=0;
void dfs2(int x,int topp){
	top[x]=topp;
	cnt++;
	id[x]=cnt;
	a[cnt]=b[x];
	if (son[x]==-1){
		return ;
	}
	dfs2(son[x],topp);
	for (int j=fi[x];j!=0;j=z[j].nex){
		int i=z[j].e;
		if (i!=son[x]&&i!=fa[x]){
			dfs2(i,i);
		}
	}
}




struct trees{
	int l,r,sum,minn,maxn;
	bool lz;
}tree[1000100];
void build(int i,int l,int r){
	tree[i].l=l;
	tree[i].lz=false;
	tree[i].r=r;
	if (l==r){
		tree[i].sum=a[l];
		tree[i].minn=a[l];
		tree[i].maxn=a[l];
		return ;
	}
	int mid=(l+r)/2;
	build(i*2,l,mid);
	build(i*2+1,mid+1,r);
	tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
	tree[i].minn=min(tree[i*2].minn,tree[i*2+1].minn);
	tree[i].maxn=max(tree[i*2].maxn,tree[i*2+1].maxn);
	return ;
}
void pushdown(int i){
	if (tree[i].lz==1){
		tree[i].lz=0;
		tree[i*2].lz=1;
		tree[i*2+1].lz=1;
		tree[i*2].sum*=-1;
		tree[i*2+1].sum*=-1;
		tree[i*2].minn*=-1;;
		tree[i*2].maxn*=-1;
		swap(tree[i*2].minn,tree[i*2].maxn);
		tree[i*2+1].minn*=-1;
		tree[i*2+1].maxn*=-1;
		swap(tree[i*2+1].minn,tree[i*2+1].maxn);
	}
	return ;
}
void add1(int i,int pos,int x){
	if (tree[i].l==tree[i].r){
		tree[i].sum=x;
		tree[i].maxn=x;
		tree[i].minn=x;
		return ;
	}
	pushdown(i);
	if (tree[i*2].r>=pos) add1(i*2,pos,x);
	else add1(i*2+1,pos,x);
	tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
	tree[i].maxn=max(tree[i*2].maxn,tree[i*2+1].maxn);
	tree[i].minn=min(tree[i*2].minn,tree[i*2+1].minn);
	return ;
}
void add2(int i,int l,int r){
	if (tree[i].l>=l&&tree[i].r<=r){
		tree[i].sum*=-1;
		tree[i].maxn*=-1;
		tree[i].minn*=-1;
		swap(tree[i].maxn,tree[i].minn);
		tree[i].lz=1;
		return ;
	}
	if (tree[i].l>r||tree[i].r<l) return ;
	pushdown(i);
	if (tree[i*2].r>=l) add2(i*2,l,r);
	if (tree[i*2+1].l<=r) add2(i*2+1,l,r);
	return ;
}
int qsum(int i,int l,int r){
	if (tree[i].l>=l&&tree[i].r<=r){
		return tree[i].sum;
	}
	if (tree[i].r<l||tree[i].l>r){
		return 0;
	}
	pushdown(i);
	int s=0;
	if (tree[i*2].r>=l) s+=qsum(i*2,l,r);
	if (tree[i*2+1].l<=r) s+=qsum(i*2+1,l,r);
	return s;
}
int qmax(int i,int l,int r){
	if (tree[i].l>=l&&tree[i].r<=r){
		return tree[i].maxn;
	}
	if (tree[i].r<l||tree[i].l>r){
		return -1e9;
	}
	pushdown(i);
	int s=-1e9;
	if (tree[i*2].r>=l) s=max(s,qmax(i*2,l,r));
	if (tree[i*2+1].l<=r) s=max(s,qmax(i*2+1,l,r));
	return s;
}
int qmin(int i,int l,int r){
	if (tree[i].l>=l&&tree[i].r<=r){
		return tree[i].minn;
	}
	if (tree[i].r<l||tree[i].l>r){
		return 1e9;
	}
	pushdown(i);
	int s=1e9;
	if (tree[i*2].r>=l) s=min(s,qmin(i*2,l,r));
	if (tree[i*2+1].l<=r) s=min(s,qmin(i*2+1,l,r));
	return s;
}//线段树部分



void q1(int i,int w){
	add1(1,id[id1[i]],w);
}
void q2(int x,int y){
	while (top[x]!=top[y]){
		if (deep[top[x]]<deep[top[y]]){
			swap(x,y);
		}
		add2(1,id[top[x]],id[x]);
		x=fa[top[x]];
	}
	if (deep[x]>deep[y]){
		swap(x,y);
	}
	if (x!=y)
	add2(1,id[x]+1,id[y]);
	return ;
}
int q3(int x,int y){
	int ans=0;
	while (top[x]!=top[y]){
		if (deep[top[x]]<deep[top[y]]){
			swap(x,y);
		}
		ans+=qsum(1,id[top[x]],id[x]);
		x=fa[top[x]];
	}
	if (deep[x]>deep[y]){
		swap(x,y);
	}
	if (x!=y)
	ans+=qsum(1,id[x]+1,id[y]);
	return ans;
}
int q4(int x,int y){
	int ans=-1e9;
	while (top[x]!=top[y]){
		if (deep[top[x]]<deep[top[y]]){
			swap(x,y);
		}
		ans=max(ans,qmax(1,id[top[x]],id[x]));
		x=fa[top[x]];
	}
	if (deep[x]>deep[y]){
		swap(x,y);
	}
	if (x!=y)
	ans=max(ans,qmax(1,id[x]+1,id[y]));
	return ans;
}
int q5(int x,int y){
	int ans=1e9;
	while (top[x]!=top[y]){
		if (deep[top[x]]<deep[top[y]]){
			swap(x,y);
		}
		ans=min(ans,qmin(1,id[top[x]],id[x]));
		x=fa[top[x]];
	}
	if (deep[x]>deep[y]){
		swap(x,y);
	}
	if (x!=y)
	ans=min(ans,qmin(1,id[x]+1,id[y]));
	return ans;
}//树链剖分

string c;
int main(){
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	scanf("%d",&n);
	for (int i=1;i<n;i++){
		int x,y,k;
		scanf("%d%d%d",&x,&y,&k);
		x++;
		y++;
		addb(x,y,k);
		z[en].i=i;
		addb(y,x,k);
		z[en].i=i;
	}
	memset(son,-1,sizeof(son));
	dfs1(1,-1,1);
	dfs2(1,1);
	build(1,1,n);
	int m;
	scanf("%d",&m);
	for (int i=1;i<=m;i++){
		cin>>c;
		int x,y;
		scanf("%d%d",&x,&y);
		if (c[0]=='C'){
			q1(x,y);
		}
		if (c[0]=='N'){
			x++;
			y++;
			q2(x,y);
		}
		if (c[0]=='S'){
			x++;
			y++;
			printf("%d\n",q3(x,y));
		}
		if (c[1]=='A'){
			x++;
			y++;
			printf("%d\n",q4(x,y));
		}
		if (c[1]=='I'){
			x++;
			y++;
			printf("%d\n",q5(x,y));
		}
	}
	return 0;
}
2023/7/31 12:18
加载中...