POJ3237树链剖分

来源:互联网 发布:jboss 关闭1099端口 编辑:程序博客网 时间:2024/06/10 06:19

CHANGE i vChange the weight of the ith edge to vNEGATE a bNegate the weight of every edge on the path from a to bQUERY a bFind the maximum weight of edges on the path from a to b

import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.Arrays;import java.util.StringTokenizer;public class Main {public static void main(String[] args) {new Task().solve() ;}}class Task {InputReader in = new InputReader(System.in);PrintWriter out = new PrintWriter(System.out);int[] size , top , son ;int[] dep , tid , fa , rank ;int dfn , edge ; int[] head , to , next ;void addEdge(int u , int v){to[edge] = v ; next[edge] = head[u] ; head[u] = edge++ ;to[edge] = u ; next[edge] = head[v] ; head[v] = edge++ ;}void findHeavyEdge(int u , int father , int depth){dep[u] = depth ; fa[u] = father ;size[u] = 1 ;for(int i = head[u] ; i != -1 ; i = next[i]){int v = to[i] ;if(v != father){findHeavyEdge(v , u , depth+1) ;size[u] += size[v] ;if(son[u] == -1 || size[v] > size[son[u]])son[u] = v ; }}}void connectHeavyEdge(int u , int tp){top[u] = tp ;tid[u] = ++dfn ; rank[tid[u]] = u ;if(son[u] == -1) return ;connectHeavyEdge(son[u] , tp) ;for(int i = head[u] ; i != -1 ; i = next[i]){int v = to[i] ;if(v != son[u] && v != fa[u])connectHeavyEdge(v , v) ;}}int[] max , min , lazy , val ; void up(int t){max[t] = Math.max(max[t<<1] , max[t<<1|1]) ;min[t] = Math.min(min[t<<1] , min[t<<1|1]) ; }void negate(int t){int tm = -max[t] ;max[t] = -min[t] ;min[t] = tm ;}void down(int t){if(lazy[t] != 0){lazy[t<<1] ^= 1 ;negate(t<<1) ;lazy[t<<1|1] ^= 1 ;negate(t<<1|1) ;lazy[t] = 0 ;}}void build(int l , int r , int t){lazy[t] = 0 ;if(l == r){max[t] = min[t] = val[l] ;return ; }int m = (l + r) >> 1 ;build(l , m , t<<1) ;build(m+1 , r , t<<1|1) ;up(t) ;}int query(int L , int R , int l , int r , int t){if(L <= l && r <= R) return max[t] ;down(t) ;int m = (l + r) >> 1 ;int res = Integer.MIN_VALUE ;if(L <= m) res = Math.max(res , query(L, R, l, m, t<<1)) ;if(R > m)  res = Math.max(res , query(L, R, m+1, r, t<<1|1)) ;up(t) ;return  res ; }void doChange(int i , int v , int l , int r , int t){if(l == r){max[t] = min[t] = v ;return ; }down(t) ;int m = (l + r) >> 1 ;if(i <= m) doChange(i, v, l, m, t<<1) ;else doChange(i, v, m+1, r, t<<1|1) ;up(t) ;} void updateByNegate(int L , int R , int l , int r , int t){if(L <= l && r <= R){negate(t) ;lazy[t] ^= 1 ; return ; }down(t) ;int m = (l + r) >> 1 ; if(L <= m) updateByNegate(L, R, l, m, t<<1) ;if(R > m) updateByNegate(L, R, m+1, r, t<<1|1) ;up(t) ;} void doNegate(int x , int y , int n){while(top[x] != top[y]){if(dep[top[x]] < dep[top[y]]){x ^= y ; y ^= x ; x ^= y ;}updateByNegate(tid[top[x]], tid[x] , 1, n, 1) ;x = fa[top[x]] ;}if(x == y) return  ;if(dep[x] > dep[y]){x ^= y ; y ^= x ; x ^= y ;}updateByNegate(tid[son[x]], tid[y], 1, n, 1) ; }int change(int x , int y , int n){if(x == y) return 0 ; int t = Integer.MIN_VALUE ;while(top[x] != top[y]){if(dep[top[x]] < dep[top[y]]){x ^= y ; y ^= x ; x ^= y ;}t = Math.max(t, query(tid[top[x]], tid[x] , 1, n, 1)) ;x = fa[top[x]] ;}if(x == y) return t ;if(dep[x] > dep[y]){x ^= y ; y ^= x ; x ^= y ;}        t = Math.max(t , query(tid[son[x]], tid[y], 1, n, 1)) ;     return t ; }class Line{int u , v , w ;Line(int u , int v , int w){this.u = u ; this.v = v ;this.w = w ; }}Line[] lines ; void init(int n){size = new int[n+1] ;top = new int[n+1] ;son = new int[n+1] ;dep = new int[n+1] ;tid = new int[n+1] ;fa = new int[n+1] ;rank = new int[n+1] ;head = new int[n+1] ;to = new int[n<<1|1] ;next = new int[n<<1|1] ;Arrays.fill(head , -1) ;Arrays.fill(son , -1) ;dfn = edge = 0 ;val = new int[n+1] ;max = new int[n<<2] ; min = new int[n<<2] ;lazy = new int[n<<2] ; lines = new Line[n+1] ;}void solve(){int t = in.nextInt() ; while(t-- > 0){int n = in.nextInt() ; init(n) ;for(int i = 1 ; i < n ; i++){   lines[i] = new Line(in.nextInt() , in.nextInt() , in.nextInt());   addEdge(lines[i].u , lines[i].v) ;}findHeavyEdge(1 , -1 , 0) ;connectHeavyEdge(1 , 1) ;for(int i = 1 ; i < n ; i++){if(tid[lines[i].u] < tid[lines[i].v]){lines[i].u ^= lines[i].v ;lines[i].v ^= lines[i].u ;lines[i].u ^= lines[i].v ;}val[tid[lines[i].u]] = lines[i].w ;}build(1, n, 1) ;while(true){String type = in.next() ;if("DONE".equals(type)) break  ;if("QUERY".equals(type))  out.println(change(in.nextInt() , in.nextInt() , n)) ;else if("CHANGE".equals(type)) doChange(tid[lines[in.nextInt()].u], in.nextInt() , 1, n, 1) ;else doNegate(in.nextInt(), in.nextInt(), n) ;}out.flush() ; }}}class InputReader {public BufferedReader reader;public StringTokenizer tokenizer;public InputReader(InputStream stream) {reader = new BufferedReader(new InputStreamReader(stream), 32768);tokenizer = new StringTokenizer("");}private void eat(String s) {tokenizer = new StringTokenizer(s);}public String nextLine() {try {return reader.readLine();} catch (Exception e) {return null;}} public boolean hasNext() {while (!tokenizer.hasMoreTokens()) {String s = nextLine();if (s == null)return false;eat(s);}return true;}public String next() {hasNext();return tokenizer.nextToken();}public int nextInt() {return Integer.parseInt(next());}public long nextLong() {return Long.parseLong(next());}public double nextDouble() {return Double.parseDouble(next());}public BigInteger nextBigInteger() {return new BigInteger(next());}}


0 0
原创粉丝点击