zoukankan      html  css  js  c++  java
  • 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|1
    using 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
    ",ask(u,v));
    			else change(u,v);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    phalcon—— PHP基础知识(一)
    仿淘宝商品浏览界面, 向上拉查看详情
    linux执行run文件显示cannot execute binary file
    atitit.client连接oracle数据库的方式总结
    LeetCode203:Remove Linked List Elements
    DotNetBar.Bar图标列表的使用
    3509.com 纵横天下虚拟主机,垃圾中的战斗机
    RT-Thread内核之线程调度(三)
    CSDN-Code平台公钥设置
    2014年工作中遇到的20个问题:81-100
  • 原文地址:https://www.cnblogs.com/jihe/p/5987263.html
Copyright © 2011-2022 走看看