poj 3237 Tree

题意:给一棵节点数不超过10000的树,有三种操作:

    1.询问a,b路径上最大的边权;

    2.修改第i条边的边权;

    3.将a->b路径上所有边的边权取反。

解法:

  spoj375加强版,将点映射到线段树之后,需要用线段树的成段更新来支持操作三,其余的和spoj那题做法一样。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define N 10010
  5 #define lson l,m,n<<1
  6 #define rson m+1,r,n<<1|1
  7 using namespace std;
  8 const int inf=1<<30;
  9 struct Edge{
 10     int u,v,len,next;
 11     Edge(){}
 12     Edge(int _u,int _v,int _len,int _next){
 13         u=_u;v=_v;len=_len;next=_next;
 14     }
 15 }edge[N<<1],e[N];
 16 int head[N],cnt;
 17 int sz[N],son[N],top[N],hash[N],fa[N],dep[N],num;
 18 void init(){
 19     memset(head,-1,sizeof(head));
 20     cnt=num=0;
 21 }
 22 void add(int u,int v,int len){
 23     edge[cnt]=Edge(u,v,len,head[u]);head[u]=cnt++;
 24     edge[cnt]=Edge(v,u,len,head[v]);head[v]=cnt++;
 25 }
 26 void dfs(int u,int d){
 27     sz[u]=1;son[u]=0;dep[u]=d;
 28     for(int k=head[u];k!=-1;k=edge[k].next){
 29         int v=edge[k].v;
 30         if(v==fa[u])continue;
 31         fa[v]=u;
 32         dfs(v,d+1);
 33         sz[u]+=sz[v];
 34         if(sz[v]>sz[son[u]])son[u]=v;
 35     }
 36 }
 37 void build_tree(int u,int pre){
 38     hash[u]=++num;top[u]=pre;
 39     if(son[u])build_tree(son[u],pre);
 40     for(int k=head[u];k!=-1;k=edge[k].next){
 41         int v=edge[k].v;
 42         if(v!=fa[u]&&v!=son[u])build_tree(v,v);
 43     }
 44 }
 45 struct segtree{
 46     int maxn[N<<2],minn[N<<2];
 47     bool flag[N<<2];
 48     void build(int l,int r,int n){
 49         maxn[n]=-inf;
 50         minn[n]=inf;
 51         flag[n]=0;
 52         if(l==r)return;
 53         int m=(l+r)>>1;
 54         build(lson);
 55         build(rson);
 56     }
 57     void pushup(int n){
 58         maxn[n]=max(maxn[n<<1],maxn[n<<1|1]);
 59         minn[n]=min(minn[n<<1],minn[n<<1|1]);
 60     }
 61     void pushdown(int n){
 62         if(flag[n]){
 63             flag[n<<1]^=1;
 64             flag[n<<1|1]^=1;
 65             int mx,mn;
 66             mx=maxn[n<<1],mn=minn[n<<1];
 67             maxn[n<<1]=-mn;minn[n<<1]=-mx;
 68             mx=maxn[n<<1|1],mn=minn[n<<1|1];
 69             maxn[n<<1|1]=-mn;minn[n<<1|1]=-mx;
 70             flag[n]=0;
 71         }
 72     }
 73     void update_1(int ll,int rr,int l,int r,int n){
 74         if(ll==l&&rr==r){
 75             flag[n]^=1;
 76             int mx=maxn[n],mn=minn[n];
 77             maxn[n]=-mn;
 78             minn[n]=-mx;
 79             return;
 80         }
 81         pushdown(n);
 82         int m=(l+r)>>1;
 83         if(rr<=m)update_1(ll,rr,lson);
 84         else if(ll>m)update_1(ll,rr,rson);
 85         else update_1(ll,m,lson),update_1(m+1,rr,rson);
 86         pushup(n);
 87     }
 88     void update_2(int nn,int x,int l,int r,int n){
 89         if(l==r){
 90             flag[n]=0;
 91             maxn[n]=minn[n]=x;
 92             return;
 93         }
 94         int m=(l+r)>>1;
 95         pushdown(n);
 96         if(nn<=m)update_2(nn,x,lson);
 97         else update_2(nn,x,rson);
 98         pushup(n);
 99     }
100     int query(int ll,int rr,int l,int r,int n){
101         if(ll==l&&rr==r)return maxn[n];
102         int m=(l+r)>>1;
103         pushdown(n);
104         if(rr<=m)return query(ll,rr,lson);
105         else if(ll>m)return query(ll,rr,rson);
106         else return max(query(ll,m,lson),query(m+1,rr,rson));
107     }
108 }seg;
109 int Query(int a,int b,int n){
110     int ta=top[a],tb=top[b],ans=-inf;
111     while(ta!=tb){
112         if(dep[ta]<dep[tb]){
113             swap(ta,tb);swap(a,b);
114         }
115         ans=max(ans,seg.query(hash[ta],hash[a],1,n,1));
116         a=fa[ta];ta=top[a];
117     }
118     if(a==b)return ans;
119     if(dep[a]>dep[b])swap(a,b);
120     return max(ans,seg.query(hash[son[a]],hash[b],1,n,1));
121 }
122 void Update(int a,int b,int n){
123     int ta=top[a],tb=top[b];
124     while(ta!=tb){
125         if(dep[ta]<dep[tb]){
126             swap(ta,tb);swap(a,b);
127         }
128         seg.update_1(hash[ta],hash[a],1,n,1);
129         a=fa[ta];ta=top[a];
130     }
131     if(a==b)return;
132     if(dep[a]>dep[b])swap(a,b);
133     seg.update_1(hash[son[a]],hash[b],1,n,1);
134 }
135 
136 int main(){
137     int t,n,a,b;
138     char op[10];
139     scanf("%d",&t);
140     while(t--){
141         init();
142         scanf("%d",&n);
143         for(int i=1;i<n;i++){
144             scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].len);
145             add(e[i].u,e[i].v,e[i].len);
146         }
147         dfs(1,1);
148         build_tree(1,1);
149         seg.build(1,n,1);
150         for(int i=1;i<n;i++){
151             if(dep[e[i].u]>dep[e[i].v])
152                 swap(e[i].u,e[i].v);
153             seg.update_2(hash[e[i].v],e[i].len,1,n,1);
154         }
155         while(scanf("%s",op)&&op[0]!='D'){
156             scanf("%d%d",&a,&b);
157             if(op[0]=='C'){
158                 seg.update_2(hash[e[a].v],b,1,n,1);
159             }else if(op[0]=='N'){
160                 Update(a,b,n);
161             }else if(op[0]=='Q'){
162                 int ans=Query(a,b,n);
163                 printf("%d\n",ans);
164             }
165         }
166     }
167     return 0;
168 }

 

posted @ 2013-02-08 20:11  silver__bullet  阅读(231)  评论(0编辑  收藏  举报