题目大意:指定一颗树上有3个操作:询问操作,询问a点和b点之间的路径上最长的那条边的长度;取反操作,将a点和b点之间的路径权值都取相反数;变化操作,把某条边的权值变成指定的值。
  1 #include <cstdio>
  2 #include <iostream>
  3 #include <cstring>
  4 
  5 using namespace std;
  6 #define N 10010
  7 #define ls o<<1
  8 #define rs o<<1|1
  9 #define define_m int m=(l+r)>>1
 10 const int INF = 2000000000;
 11 int first[N] , k;
 12 struct Edge{
 13     int x , y , next , w;
 14     Edge(){}
 15     Edge(int x , int y , int next , int w):x(x),y(y),next(next),w(w){}
 16 }e[N<<1];
 17 
 18 void add_edge(int x ,int y , int w)
 19 {
 20     e[k] = Edge(x , y , first[x] , w);
 21     first[x] = k++;
 22 }
 23 
 24 int sz[N] , son[N] , dep[N] , fa[N] , num , id[N] , top[N];
 25 void dfs(int u , int f , int d)
 26 {
 27     sz[u] = 1 , fa[u] = f , son[u] = 0 , dep[u] = d;
 28     int maxn = 0;
 29     for(int i=first[u] ; ~i ; i=e[i].next){
 30         int v = e[i].y;
 31         if(v == f) continue;
 32         dfs(v , u , d+1);
 33         sz[u] += sz[v];
 34         if(maxn<sz[v]) maxn = sz[v] , son[u] = v;
 35     }
 36 }
 37 
 38 void dfs1(int u , int f , int head)
 39 {
 40     id[u] = ++num , top[u] = head;
 41     if(son[u]) dfs1(son[u] , u , head);
 42     for(int i=first[u] ; ~i ; i=e[i].next){
 43         int v = e[i].y;
 44         if(v == f || v==son[u]) continue;
 45         dfs1(v , u , v);
 46     }
 47 }
 48 
 49 int mx[N<<2] , mn[N<<2] , neg[N<<2] , val[N];
 50 
 51 void push_down(int o)
 52 {
 53     if(neg[o]<0){
 54         neg[ls]*=neg[o] , neg[rs]*=neg[o];
 55         int tmp;
 56         tmp = mx[ls] , mx[ls] = -mn[ls] , mn[ls] = -tmp;
 57         tmp = mx[rs] , mx[rs] = -mn[rs] , mn[rs] = -tmp;
 58         neg[o] = 1;
 59     }
 60 }
 61 
 62 void push_up(int o)
 63 {
 64     mx[o] = max(mx[ls] , mx[rs]);
 65     mn[o] = min(mn[ls] , mn[rs]);
 66 }
 67 
 68 void build(int o , int l , int r)
 69 {
 70     neg[o] = 1;
 71     if(l==r){
 72         mx[o] = mn[o] = val[l];
 73         return ;
 74     }
 75     define_m;
 76     build(ls , l , m);
 77     build(rs , m+1 , r);
 78     push_up(o);
 79 }
 80 
 81 void change(int o , int l , int r , int p , int v)
 82 {
 83     if(l==r){
 84         mx[o] = mn[o] = v;
 85         return;
 86     }
 87     push_down(o);
 88     define_m;
 89     if(m>=p) change(ls , l , m , p , v);
 90     else change(rs , m+1 , r , p , v);
 91     push_up(o);
 92 }
 93 
 94 void update(int o , int l , int r , int s , int t)
 95 {
 96     if(l>=s && r<=t){
 97         int tmp;
 98         tmp = mx[o] , mx[o] = -mn[o] , mn[o] = -tmp;
 99         neg[o] *= -1;
100         return ;
101     }
102     push_down(o);
103     define_m;
104     if(m>=s) update(ls , l , m , s , t);
105     if(m<t) update(rs , m+1 , r , s , t);
106     push_up(o);
107 }
108 
109 int query(int o , int l , int r , int s , int t)
110 {
111     if(l>=s && r<=t) return mx[o];
112     push_down(o);
113     define_m;
114     int ans = -INF;
115     if(m>=s) ans=max(ans , query(ls , l , m , s , t));
116     if(m<t) ans=max(ans , query(rs , m+1 , r , s , t));
117     return ans;
118 }
119 int n , u , v , w;
120 char str[10];
121 
122 void negatePath(int u , int v)
123 {
124     int top1 = top[u] , top2 = top[v];
125     while(top1!=top2)
126     {
127         if(dep[top1]<dep[top2]){
128             swap(top1 , top2);
129             swap(u , v);
130         }
131         update(1 , 2 , num , id[top1] , id[u]);
132         u = fa[top1];
133         top1 = top[u];
134     }
135     if(u!=v){
136         if(dep[u]<dep[v]) swap(u , v);
137         update(1 , 2 , num , id[son[v]] , id[u]);
138     }
139 }
140 
141 int calPath(int u , int v)
142 {
143     int top1 = top[u] , top2 = top[v];
144     int ret = -INF;
145     while(top1!=top2){
146         if(dep[top1]<dep[top2]){
147             swap(top1 , top2);
148             swap(u , v);
149         }
150         ret = max(ret , query(1 , 2 , num , id[top1] , id[u]));
151         u = fa[top1];
152         top1 = top[u];
153     }
154     if(u!=v){
155         if(dep[u]<dep[v]) swap(u , v);
156         ret = max(ret , query(1 , 2 , num , id[son[v]] , id[u]));
157     }
158     return ret;
159 }
160 
161 int main()
162 {
163   //  freopen("in.txt" , "r" , stdin);
164     int T;
165     scanf("%d" , &T);
166     while(T--)
167     {
168         scanf("%d" , &n);
169         memset(first , -1  , sizeof(first));
170         k=0;
171         for(int i=0 ; i<n-1 ; i++){
172             scanf("%d%d%d" , &u ,&v , &w);
173             add_edge(u , v , w);
174             add_edge(v , u , w);
175         }
176         num = 0;
177         dfs(1 , 0 , 1);
178         dfs1(1 , 0 , 1);
179         for(int i=0 ; i<n ; i++){
180             int j=i<<1 , x=e[j].x , y=e[j].y;
181             if(fa[x]!=y) val[id[y]] = e[j].w;
182             else val[id[x]] = e[j].w;
183         }
184         build(1 , 2 , num);
185         while(scanf("%s" , str)){
186             if(str[0] == 'D') break;
187             if(str[0] == 'C'){
188                 scanf("%d%d" , &u , &v);
189                 u--;
190                 int x = e[u*2].x , y = e[u*2].y , pos;
191                 if(fa[x]!=y) pos = id[y];
192                 else pos = id[x];
193                 change(1 , 2 , num , pos , v);
194             }
195             else if(str[0] == 'N'){
196                 scanf("%d%d" , &u , &v);
197                 negatePath(u , v);
198             }
199             else{
200                 scanf("%d%d" , &u , &v);
201                 int ret = calPath(u , v);
202                 printf("%d\n" , ret);
203             }
204         }
205     }
206     return 0;
207 }

 

 posted on 2015-08-27 17:26  Love风吟  阅读(252)  评论(0编辑  收藏  举报