题目大意:指定一颗树上有3个操作:询问操作,询问a点和b点之间的路径上最长的那条边的长度;取反操作,将a点和b点之间的路径权值都取相反数;变化操作,把某条边的权值变成指定的值。
1 #include2 #include 3 #include 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 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 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 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 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 ){ 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 }