今天疯狂星期四,可惜只过了样例,help!
查看原帖
今天疯狂星期四,可惜只过了样例,help!
173792
MarioChan楼主2022/9/8 16:57
#include<iostream>
#include<limits.h>
#define MAXN 200005
using namespace std;
int n,m,u,v,w;
//==================================
struct EDGE {
	int from,to,next,w;
} edge[MAXN<<1];
int cnt=0,head[MAXN];
inline void add_edge(int u,int v,int w) {
	++cnt;
	edge[cnt].w=w, edge[cnt].from=u, edge[cnt].to=v,edge[cnt].next=head[u];
	head[u]=cnt;
}
//====================================
int x,father[MAXN],depth[MAXN],siz[MAXN],val[MAXN], son[MAXN];
inline void dfs1(int x,int fa,int deep,const int& edge_num) {
	depth[x]=deep, father[x]=fa, val[x]=edge[edge_num].w;
	siz[x]=1;//标记树大小
	int maxson=-1;//记录重儿子的儿子数
	for(int i=head[x],v; i; i=edge[i].next) {
		v=edge[i].to;
		if(v==fa) continue;
		dfs1(v,x,deep+1,i);
		siz[x]+=siz[v];
		if(siz[v]>maxson) son[x]=v,maxson=siz[v];//迭代重儿子
	}
}
int id[MAXN],top[MAXN],va[MAXN],tot=0;
inline void dfs2(int x,int topf) {
	//建树
	id[x]=++tot;
	va[tot]=val[x];
	top[x]=topf;
	if(!son[x]) return;
	dfs2(son[x],topf);//重儿子
	for(int i=head[x],v; i; i=edge[i].next) {
		v=edge[i].to;
		if(v==father[x]||v==son[x]) continue;
		dfs2(v,v);
	}
}
//===========================================
int query_sum(int,int,int);//提前声明
int query_max(int,int,int);//提前声明
int query_min(int,int,int);//提前声明
void changeSegment(int,int,int);
int query_two_point_sum(int x,int y) {
	int ans=0;
	while(top[x]!=top[y]) {
		if(depth[top[x]]<depth[top[y]]) swap(x,y);
		ans+=query_sum(1,id[top[x]],id[x]);
		x=father[top[x]];
	}
	if(depth[x]>depth[y]) swap(x,y);
	ans+=query_sum(1,id[x],id[y]);
	return ans;
}
int query_two_point_max(int x,int y) {
	int ans=INT_MIN;
	while(top[x]!=top[y]) {
		if(depth[top[x]]<depth[top[y]]) swap(x,y);
		ans=max(ans,query_max(1,id[top[x]],id[x]));
		x=father[top[x]];
	}
	if(depth[x]>depth[y]) swap(x,y);
	ans=max(ans,query_max(1,id[x],id[y]));
	return ans;
}
int query_two_point_min(int x,int y) {
	int ans=INT_MAX;
	while(top[x]!=top[y]) {
		if(depth[top[x]]<depth[top[y]]) swap(x,y);
		ans=min(ans,query_min(1,id[top[x]],id[x]));
		x=father[top[x]];
	}
	if(depth[x]>depth[y]) swap(x,y);
	ans=min(ans,query_min(1,id[x],id[y]));
	return ans;
}
void change_two_point(int x,int y) {//变成相反数
	while(top[x]!=top[y]) {
		if(depth[top[x]]<depth[top[y]]) swap(x,y);
		changeSegment(1,id[top[x]],id[x]);
		x=father[top[x]];
	}
	if(depth[x]>depth[y]) swap(x,y);
	changeSegment(1,id[x],id[y]);
}
//===========================================
struct NODE {
	int l,r,sum,max_val,min_val,lazy;
} node[MAXN<<2];
inline void update(const int& x) {
	node[x].max_val=max(node[x<<1].max_val,node[x<<1|1].max_val);
	node[x].min_val=min(node[x<<1].min_val,node[x<<1|1].min_val);
	node[x].sum=node[x<<1].sum+node[x<<1|1].sum;
}
void build_tree(int x,int l,int r) {
	node[x].l=l, node[x].r=r;
	if(l==r) {
		node[x].sum=node[x].min_val=node[x].max_val=va[l];
		node[x].lazy=0; 
		return;
	}
	int mid=l+r>>1;
	build_tree(x<<1,l,mid);
	build_tree(x<<1|1,mid+1,r);
	update(x);
}
void pushdown(int x) {
	if(node[x].l==node[x].r) {
		lazy[x]=0;
		return;
	}
	node[x].lazy=0;
	node[x<<1].sum*=-1, node[x<<1|1].sum*=-1;
	swap(node[x<<1].max_val, node[x<<1].min_val);
	swap(node[x<<1|1].max_val, node[x<<1|1].min_val);
	node[x<<1].max_val*=-1, node[x<<1].min_val*=-1;
	node[x<<1|1].max_val*=-1, node[x<<1|1].min_val*=-1;
	node[x<<1].lazy=(node[x<<1].lazy+1)%2, node[x<<1|1].lazy=(node[x<<1|1].lazy+1)%2;
}
void changeSegment(int x,int L,int R) {//反转区间
	if(node[x].l==L&&node[x].r==R) {
		if(node[x].lazy) {
			node[x].lazy=0;
			returm; 
		}
		node[x].sum*=-1;
		swap(node[x].max_val, node[x].min_val);
		node[x].max_val*=-1, node[x].min_val*=-1;
		node[x].lazy=1;
		return;
	}
	if(node[x].lazy) pushdown(x);
	int mid=node[x].l+node[x].r>>1;
	if(R<=mid) changeSegment(x<<1,L,R);
	else if(L>mid) changeSegment(x<<1|1,L,R);
	else changeSegment(x<<1,L,mid),changeSegment(x<<1|1,mid+1,R);
	update(x);
}
void change_one_point(const int& x,const int& target,const int& val) {
	if(node[x].l==node[x].r) {
		node[x].min_val=node[x].max_val=node[x].sum=val;
		return;
	}
	int mid=node[x].l+node[x].r>>1;
	if(target<=mid) change_one_point(x<<1,target,val);
	else change_one_point(x<<1|1,target,val);
	update(x);
}
int query_sum(int x,int L,int R) {// 求区间和
	if(node[x].l==L&&node[x].r==R) return node[x].sum;
	if(node[x].lazy) pushdown(x);
	int mid=node[x].l+node[x].r>>1;
	if(R<=mid) return query_sum(x<<1,L,R);
	else if(L>mid) return query_sum(x<<1|1,L,R);
	else return query_sum(x<<1,L,mid) + query_sum(x<<1|1,mid+1,R);
}
int query_max(int x,int L,int R) {// 求区间和
	if(node[x].l==L&&node[x].r==R) return node[x].max_val;
	if(node[x].lazy) pushdown(x);
	int mid=node[x].l+node[x].r>>1;
	if(R<=mid) return query_max(x<<1,L,R);
	else if(L>mid) return query_max(x<<1|1,L,R);
	else return max( query_max(x<<1,L,mid), query_max(x<<1|1,mid+1,R) );
}
int query_min(int x,int L,int R) {// 求区间和
	if(node[x].l==L&&node[x].r==R) return node[x].min_val;
	if(node[x].lazy) pushdown(x);
	int mid=node[x].l+node[x].r>>1;
	if(R<=mid) return query_min(x<<1,L,R);
	else if(L>mid) return query_min(x<<1|1,L,R);
	else return min( query_min(x<<1,L,mid), query_min(x<<1|1,mid+1,R) );
}
//===========================================
int main() {freopen("D:\\stdin.txt","r",stdin);
freopen("D:\\stdout.txt","w",stdout);
	cin>>n;
	for(int i=1; i<n; i++) {
		scanf("%d%d%d",&u,&v,&w);
		++u,++v;
		add_edge(u,v,w), add_edge(v,u,w);
	}
	edge[0].w=0;
	dfs1(1,0,0,0);
	dfs2(1,1);
	build_tree(1,1,n);
	int m;
	string op_code;
	cin>>m;
	while(m--) {
		cin>>op_code;
		if(op_code=="C") {
			scanf("%d%d",&u,&v);//把第u条边改成v
			int target=u*2;
			if(depth[edge[target].from]>depth[edge[target].to]) target=edge[target].from;
			else target=edge[target].to;
			change_one_point(1,id[target],v);
		} else if(op_code=="N") {
			scanf("%d%d",&u,&v);
			++u,++v;
			change_two_point(u,v);
		} else if(op_code=="SUM") {
			scanf("%d%d",&u,&v);
			++u,++v;
			printf("%d\n",query_two_point_sum(u,v));
		} else if(op_code=="MAX") {
			scanf("%d%d",&u,&v);
			++u,++v;
			printf("%d\n",query_two_point_max(u,v));
		} else if(op_code=="MIN") {
			scanf("%d%d",&u,&v);
			++u,++v;
			printf("%d\n",query_two_point_min(u,v));
		}
	}
	return 0;
}
2022/9/8 16:57
加载中...