首页 > 代码库 > poj 3237

poj 3237

题意:给一颗树,边上有权有三种操作

Q u,v  u->v路径上权的最大值

C u,v  输入时的第u条边权值修改为v

N u,v u->v路径上边的权值*-1

 按照轻重边剖分,取反加个标记就好,记录最大值最小值,取反的时候反过来,再*-1,完成取反操作

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define lc rt<<1#define rc rt<<1|1using namespace std;const int maxn=1e4+5;const int INF=1e9;struct Node{int l,r,mx,mi;bool mark;}tr[maxn*4];struct edge{int to,nxt,v;}e[maxn*3];int fa[maxn],dep[maxn],son[maxn],siz[maxn],top[maxn];int p[maxn],cnt,node,val[maxn],fp[maxn],head[maxn];void addedge(int u,int v,int w){	cnt++;e[cnt].to=v;e[cnt].nxt=head[u];	e[cnt].v=w;head[u]=cnt;}void dfs1(int u){	siz[u]=1;son[u]=0;	for(int i=head[u];i;i=e[i].nxt){		int v=e[i].to;		if(v==fa[u])continue;		fa[v]=u;dep[v]=dep[u]+1;val[v]=e[i].v;		dfs1(v);		siz[u]+=siz[v];		if(siz[v]>siz[son[u]])son[u]=v;	}}void dfs2(int u,int sp){	p[u]=++node;top[u]=sp;fp[node]=u;	if(son[u])dfs2(son[u],top[u]);	for(int i=head[u];i;i=e[i].nxt){		int v=e[i].to;		if(v!=fa[u]&&v!=son[u])dfs2(v,v);	}}inline void pushup(int rt){	tr[rt].mx=max(tr[lc].mx,tr[rc].mx);	tr[rt].mi=min(tr[lc].mi,tr[rc].mi);}inline void pushdown(int rt){	if(tr[rt].mark){		swap(tr[lc].mi,tr[lc].mx);tr[lc].mi*=-1;		swap(tr[rc].mi,tr[rc].mx);tr[rc].mi*=-1;		tr[lc].mx*=-1;tr[rc].mx*=-1;		tr[lc].mark^=1;tr[rc].mark^=1;		tr[rt].mark^=1;	}}void build(int rt,int l,int r){	tr[rt].l=l;tr[rt].r=r;tr[rt].mark=false;	if(l==r){		tr[rt].mi=tr[rt].mx=val[fp[l]];	}	else{		int m=(l+r)>>1;		build(lc,l,m);build(rc,m+1,r);		pushup(rt);	}}void update(int rt,int pp,int v){	int l=tr[rt].l,r=tr[rt].r;	if(l==r)tr[rt].mx=tr[rt].mi=v;	else{		pushdown(rt);		int m=(l+r)>>1;		if(pp<=m)update(lc,pp,v);		else update(rc,pp,v);		pushup(rt);	}}void anti(int rt,int a,int b){	int l=tr[rt].l,r=tr[rt].r;	if(l==a&&b==r){		tr[rt].mark^=1;swap(tr[rt].mx,tr[rt].mi);		tr[rt].mx*=-1;tr[rt].mi*=-1;	}	else{		pushdown(rt);		int m=(l+r)>>1;		if(b<=m) anti(lc,a,b);		else if(m<a)anti(rc,a,b);		else anti(lc,a,m),anti(rc,m+1,b);		pushup(rt);	}}int query(int rt,int a,int b){	int l=tr[rt].l,r=tr[rt].r;	if(l==a&&b==r)return tr[rt].mx;	else{		pushdown(rt);		int m=(l+r)>>1;		if(b<=m)return query(lc,a,b);		else if(m<a)return query(rc,a,b);		else return max(query(lc,a,m),query(rc,m+1,b));	}}void change(int u,int v){	while(top[u]!=top[v]){		if(dep[top[u]]<dep[top[v]])swap(u,v);		anti(1,p[top[u]],p[u]);		u=fa[top[u]];	}	if(u==v)return ;	if(dep[u]>dep[v])swap(u,v);	anti(1,p[son[u]],p[v]);}int ask(int u,int v){	int ans=-INF;	while(top[u]!=top[v]){		if(dep[top[u]]<dep[top[v]])swap(u,v);		ans=max(ans,query(1,p[top[u]],p[u]));		u=fa[top[u]];	}	if(u==v)return ans;	if(dep[u]>dep[v])swap(u,v);	return max(ans,query(1,p[son[u]],p[v]));}int ee[maxn][2],u,v,w;int main(){	int t,n;scanf("%d",&t);	while(t--){		scanf("%d",&n);		cnt=node=0;memset(head,0,sizeof(head));		for(int i=1;i<n;i++){			scanf("%d%d%d",&ee[i][0],&ee[i][1],&w);			addedge(ee[i][0],ee[i][1],w);			addedge(ee[i][1],ee[i][0],w);		}		dfs1(1);dfs2(1,1);		build(1,1,n);		char op[10];		for(int i=1;i<n;i++)if(dep[ee[i][0]]>dep[ee[i][1]])swap(ee[i][0],ee[i][1]);		while(true){			scanf("%s",op);			if(op[0]==‘D‘)break;			scanf("%d%d",&u,&v);			if(op[0]==‘C‘){				u=ee[u][1];				update(1,p[u],v);			}			else if(op[0]==‘Q‘)printf("%d\n",ask(u,v));			else change(u,v);		}	}	return 0;}

 

poj 3237