POJ 3237 Tree

题意是在一棵树上 的边上进行三个操作:

1.修改某条变得值

2.反转一条边的值

3.求出一条边上的max;

树上的操作+线段树

翻转的处理比较难 其他都是以前正常的线段树处理

翻转类似LAZY思想 ,然后我们设定MIN ,MAX,因为-MAX就是MIN 了,

线段树用回以前的版本了;

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <string>
  4 #include <cmath>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <queue>
  8 #include <cstdlib>
  9 #include <stack>
 10 #include <vector>
 11 #include <set>
 12 #include <map>
 13 using namespace std;
 14 #define N 132222
 15 int head[N],top[N],fa[N],tot;
 16 int son[N],p[N],fp[N],dep[N],pos;
 17 int sz[N];
 18 void init()
 19 {
 20     memset(head,-1,sizeof(head));
 21     tot=0;
 22     pos=0;
 23     memset(son,-1,sizeof(son));
 24 }
 25 struct edge
 26 {
 27     int v,next;
 28 }e[N<<1];
 29 void add(int u,int v)
 30 {
 31    e[tot].v=v;
 32    e[tot].next=head[u];
 33    head[u]=tot++;
 34 }
 35 void dfs(int u,int f,int d)
 36 {
 37     dep[u]=d;
 38     fa[u]=f;
 39     sz[u]=1;
 40     for (int i=head[u];i!=-1;i=e[i].next)
 41     {
 42         int v=e[i].v;
 43         if (v==f) continue;
 44         dfs(v,u,d+1);
 45         sz[u]+=sz[v];
 46         if (son[u]==-1||sz[son[u]]<sz[v]) son[u]=v;
 47     }
 48 }
 49 
 50 void getpos(int u,int sp)
 51 {
 52     top[u]=sp;
 53     p[u]=++pos;
 54     fp[pos]=u;
 55     if (son[u]==-1) return;
 56     getpos(son[u],sp);
 57     for (int i=head[u];i!=-1;i=e[i].next)
 58     {
 59         int v=e[i].v;
 60         if (v!=son[u]&&v!=fa[u])
 61             getpos(v,v);
 62     }
 63 }
 64 
 65 
 66 struct node
 67 {
 68     int l,r,Min,Max,flag;
 69 }tree[N<<2];
 70 void build(int l,int r,int rt)
 71 {
 72     tree[rt].l=l;
 73     tree[rt].r=r;
 74     tree[rt].Min=tree[rt].Max=0;
 75     tree[rt].flag=0;
 76     if (l==r) return;
 77     int m=(l+r)>>1;
 78     build(l,m,rt<<1);
 79     build(m+1,r,rt<<1|1);
 80 }
 81 
 82 void pushup(int rt)
 83 {
 84     tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max);
 85     tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min);
 86 }
 87 
 88 void pushdown(int rt)
 89 {
 90     if (tree[rt].l==tree[rt].r) return;
 91     if (tree[rt].flag)
 92     {
 93         tree[rt<<1].Max=-tree[rt<<1].Max;
 94         tree[rt<<1].Min=-tree[rt<<1].Min;
 95         swap(tree[rt<<1].Max,tree[rt<<1].Min);
 96 
 97         tree[rt<<1|1].Max=-tree[rt<<1|1].Max;
 98         tree[rt<<1|1].Min=-tree[rt<<1|1].Min;
 99         swap(tree[rt<<1|1].Max,tree[rt<<1|1].Min);
100         tree[rt<<1].flag^=1;
101         tree[rt<<1|1].flag^=1;
102         tree[rt].flag=0;
103     }
104 }
105 
106 void update(int p,int c,int rt)
107 {
108     if (tree[rt].l==p&&tree[rt].r==p)
109     {
110         tree[rt].Max=c;
111         tree[rt].Min=c;
112         tree[rt].flag=0;
113         return;
114     }
115     pushdown(rt);
116     int mid=(tree[rt].l+tree[rt].r)>>1;
117     if (p<=mid) update(p,c,rt<<1);
118     else update(p,c,rt<<1|1);
119     pushup(rt);
120 }
121 
122 void neupdate(int l,int r,int rt)
123 {
124     if (tree[rt].l==l&&tree[rt].r==r)
125     {
126         tree[rt].Max=-tree[rt].Max;
127         tree[rt].Min=-tree[rt].Min;
128         swap(tree[rt].Max,tree[rt].Min);
129         tree[rt].flag^=1;
130         return;
131     }
132     pushdown(rt);
133     int mid=(tree[rt].l+tree[rt].r)>>1;
134     if (r<=mid) neupdate(l,r,rt<<1);
135     else if (l>mid) neupdate(l,r,rt<<1|1);
136     else
137     {
138         neupdate(l,mid,rt<<1);
139         neupdate(mid+1,r,rt<<1|1);
140     }
141     pushup(rt);
142 }
143 
144 int query(int l,int r,int rt)
145 {
146     if (tree[rt].l==l&&tree[rt].r==r) return tree[rt].Max;
147     pushdown(rt);
148     int mid=(tree[rt].l+tree[rt].r)>>1;
149     if (r<=mid) return query(l,r,rt<<1);
150     else if (l>mid) return query(l,r,rt<<1|1);
151     else return max(query(l,mid,rt<<1),query(mid+1,r,rt<<1|1));
152     pushup(rt);
153 }
154 
155 int lca(int u,int v)
156 {
157     int fu=top[u],fv=top[v];
158     int tmp=-1234567;
159     while (fu!=fv)
160     {
161         if (dep[fu]<dep[fv])
162         {
163             swap(fu,fv);
164             swap(u,v);
165         }
166         tmp=max(tmp,query(p[fu],p[u],1));
167         u=fa[fu];
168         fu=top[u];
169     }
170     if (u==v) return tmp;
171     if (dep[u]>dep[v]) swap(u,v);
172     return max(tmp,query(p[son[u]],p[v],1));
173 }
174 
175 void Negat(int u,int v)
176 {
177     int fu=top[u],fv=top[v];
178     while (fu!=fv)
179     {
180         if (dep[fu]<dep[fv])
181         {
182             swap(fu,fv);
183             swap(u,v);
184         }
185         neupdate(p[fu],p[u],1);
186         u=fa[fu];
187         fu=top[u];
188     }
189     if (u==v) return;
190     if (dep[u]>dep[v]) swap(u,v);
191     neupdate(p[son[u]],p[v],1);
192 }
193 
194 int a[N][3];
195 int main()
196 {
197     int T;
198     scanf("%d",&T);
199     while (T--)
200     {
201         int n;
202         init();
203         scanf("%d",&n);
204         for (int i=1;i<n;i++){
205             scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);
206             add(a[i][0],a[i][1]);
207             add(a[i][1],a[i][0]);
208         }
209 
210         dfs(1,0,0);
211         getpos(1,1);
212         build(1,pos,1);
213         for (int i=1;i<n;i++)
214         {
215             if (dep[a[i][0]]>dep[a[i][1]]) swap(a[i][0],a[i][1]);
216             update(p[a[i][1]],a[i][2],1);
217         }
218          //printf("rerEt\n");
219 
220         char s[10];
221         while (scanf("%s",s)!=EOF)
222         {
223             if (s[0]=='D') break;
224             int u,v;
225             scanf("%d%d",&u,&v);
226             if (s[0]=='Q')
227                printf("%d\n",lca(u,v));
228             else if (s[0]=='N') Negat(u,v);
229             else  update(p[a[u][1]],v,1);
230         }
231     }
232     return 0;
233 }

 

posted on 2015-02-23 22:25  forgot93  阅读(118)  评论(0编辑  收藏  举报

导航