POJ 3237:Tree

Posted 这里有十二吨芒果

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3237:Tree相关的知识,希望对你有一定的参考价值。

技术分享
Tree
Time Limit: 5000MS        Memory Limit: 131072K
Total Submissions: 10224        Accepted: 2651
Description

You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N ? 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions can be one of the following forms:

CHANGE i v    Change the weight of the ith edge to v
NEGATE a b    Negate the weight of every edge on the path from a to b
QUERY a b    Find the maximum weight of edges on the path from a to b
Input

The input contains multiple test cases. The first line of input contains an integer t (t ≤ 20), the number of test cases. Then follow the test cases.

Each test case is preceded by an empty line. The first nonempty line of its contains N (N ≤ 10,000). The next N ? 1 lines each contains three integers a, b and c, describing an edge connecting nodes a and b with weight c. The edges are numbered in the order they appear in the input. Below them are the instructions, each sticking to the specification above. A lines with the word “DONE” ends the test case.

Output

For each “QUERY” instruction, output the result on a separate line.

Sample Input

1

3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE
Sample Output

1
3
题目

  芒果君:比较裸的树剖,然而我调了一下午……总共三个操作:修改单边权、查询路径上所有路的最大值或所有路的权值取相反数。第三个最难搞,因为本来维护好的最大值会变成最小值,那再维护下最小值不就完了……思路简单的不行然而代码量太大堪比线段树练习5 QAQ 注意中间的ret是负无穷!我简直要调到死了

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<map>
  5 #define maxn 100010
  6 #define inf 1<<29
  7 using namespace std;
  8 int top[maxn],deep[maxn],size[maxn],head[maxn],son[maxn],fa[maxn],dfn[maxn],tot,cnt,hl[maxn],n,q,lazy[maxn];
  9 char s[10];
 10 struct Edge{
 11     int u,v,w,ne;
 12 }e[maxn<<1];
 13 struct Tree{
 14     int mi,ma;
 15 }tree[maxn<<2];
 16 void init()
 17 {
 18     cnt=tot=0;
 19     memset(tree,0,sizeof(tree));
 20     memset(top,0,sizeof(top));
 21     memset(deep,0,sizeof(deep));
 22     memset(size,0,sizeof(size));
 23     memset(head,0,sizeof(head));
 24     memset(son,0,sizeof(son));
 25     memset(fa,0,sizeof(fa));
 26     memset(dfn,0,sizeof(dfn));
 27     memset(hl,0,sizeof(hl));
 28     memset(lazy,0,sizeof(lazy));
 29 }
 30 void add(int u,int v,int w)
 31 {
 32     e[++cnt].u=u;
 33     e[cnt].v=v;
 34     e[cnt].w=w;
 35     e[cnt].ne=hl[u];
 36     hl[u]=cnt;
 37 }
 38 void dfs1(int x)
 39 {
 40     size[x]=1;
 41     for(int i=hl[x];i;i=e[i].ne){
 42         int v=e[i].v;
 43         if(v==fa[x]) continue;
 44         deep[v]=deep[x]+1;
 45         fa[v]=x;
 46         dfs1(v);
 47         size[x]+=size[v];
 48         if(size[v]>size[son[x]]) son[x]=v;
 49     }
 50 }
 51 void dfs2(int x,int tp)
 52 {
 53     top[x]=tp;
 54     dfn[x]=++tot;
 55     if(son[x]) dfs2(son[x],tp);
 56     for(int i=hl[x];i;i=e[i].ne){
 57         int v=e[i].v;
 58         if(v==son[x]||v==fa[x]) continue;
 59         dfs2(v,v);
 60     }
 61 }
 62 void pushup(int o)
 63 {
 64     tree[o].ma=max(tree[o<<1].ma,tree[o<<1|1].ma);
 65     tree[o].mi=min(tree[o<<1].mi,tree[o<<1|1].mi);
 66 }
 67 void pushdown(int o,int l,int r)
 68 {
 69     if(l==r||!lazy[o]) return;
 70     lazy[o]=0;
 71     lazy[o<<1]^=1,lazy[o<<1|1]^=1;
 72     swap(tree[o<<1].mi,tree[o<<1].ma);
 73     tree[o<<1].mi*=-1,tree[o<<1].ma*=-1;
 74     swap(tree[o<<1|1].mi,tree[o<<1|1].ma);
 75     tree[o<<1|1].mi*=-1,tree[o<<1|1].ma*=-1;
 76 }
 77 void update(int o,int l,int r,int x,int val)
 78 {
 79     if(l==r){
 80         tree[o].ma=tree[o].mi=val;
 81         lazy[o]=0;
 82         return;
 83     }
 84     pushdown(o,l,r);
 85     int mid=(l+r)>>1;
 86     if(x<=mid) update(o<<1,l,mid,x,val);
 87     else update(o<<1|1,mid+1,r,x,val);
 88     pushup(o);
 89 }
 90 int query(int o,int l,int r,int ql,int qr)
 91 {
 92     if(l>=ql&&r<=qr) return tree[o].ma;
 93     pushdown(o,l,r);
 94     int ret=-inf;
 95     int mid=(l+r)>>1;
 96     if(ql<=mid) ret=max(ret,query(o<<1,l,mid,ql,qr));
 97     if(qr>mid) ret=max(ret,query(o<<1|1,mid+1,r,ql,qr));
 98     pushup(o);
 99     return ret;
100 }
101 int getmax(int x,int y)
102 {
103     int fx=top[x],fy=top[y],ret=-inf;
104     while(fx!=fy){
105         if(deep[fx]>deep[fy]){
106             swap(x,y);
107             swap(fx,fy);
108         }
109         ret=max(ret,query(1,1,n,dfn[fy],dfn[y]));
110         y=fa[fy];
111         fy=top[y];
112     }
113     if(x==y) return ret;
114     if(deep[x]>deep[y]) swap(x,y);
115     return max(ret,query(1,1,n,dfn[son[x]],dfn[y]));
116 }
117 void rever(int o,int l,int r,int ql,int qr)
118 {
119     if(l>=ql&&r<=qr){
120         lazy[o]^=1;
121         swap(tree[o].mi,tree[o].ma);
122         tree[o].mi*=-1,tree[o].ma*=-1;
123         return;
124     }
125     pushdown(o,l,r);
126     int mid=(l+r)>>1;
127     if(ql<=mid) rever(o<<1,l,mid,ql,qr);
128     if(qr>mid) rever(o<<1|1,mid+1,r,ql,qr);
129     pushup(o);
130 }
131 void Negate(int x,int y)
132 {
133     int fx=top[x],fy=top[y];
134     while(fx!=fy){
135         if(deep[fx]>deep[fy]){
136             swap(x,y);
137             swap(fx,fy);
138         }
139         rever(1,1,n,dfn[fy],dfn[y]);
140         y=fa[fy];
141         fy=top[y];
142     }
143     if(x==y) return;
144     if(deep[x]>deep[y]) swap(x,y);
145     rever(1,1,n,dfn[son[x]],dfn[y]);
146 }
147 int main()
148 {
149     int T,x,y,w;
150     scanf("%d",&T);
151     while(T--){
152         init();
153         scanf("%d",&n);
154         for(int i=1;i<n;++i){
155             scanf("%d%d%d",&x,&y,&w);
156             add(x,y,w);
157             add(y,x,w);
158         }
159         dfs1(1);
160         dfs2(1,1);
161         for(int i=1;i<=2*n-2;i+=2){
162             int u=e[i].u,v=e[i].v;
163             if(deep[u]>deep[v]) swap(u,v);
164             update(1,1,n,dfn[v],e[i].w);
165         }
166         while(scanf("%s",s)!=EOF){
167             if(s[0]==D) break;
168             scanf("%d%d",&x,&y);
169             if(s[0]==N) Negate(x,y);
170             else if(s[0]==C){
171                 x=x*2-1;
172                 int u=e[x].u,v=e[x].v;
173                 if(deep[u]>deep[v]) swap(u,v);
174                 update(1,1,n,dfn[v],y);
175             }
176             else printf("%d\n",getmax(x,y));
177         }
178         
179     }
180     return 0;
181 }

 

以上是关于POJ 3237:Tree的主要内容,如果未能解决你的问题,请参考以下文章

POJ3237Tree 树链剖分+线段树

poj3237 Tree

●POJ 3237 Tree

poj 3237 Tree(树链剖分,线段树)

[POJ3237]Tree

POJ 3237 (Tree)