1. 程式人生 > >二叉樹搜尋樹之線段樹

二叉樹搜尋樹之線段樹

有志者,事竟成,破釜沉舟,百二秦關終屬楚; 苦心人,天不負,臥薪嚐膽,三千越甲可吞吳!

題目地址:

http://acm.hdu.edu.cn/showproblem.php?pid=1754

參考資料:

https://www.cnblogs.com/TheRoadToTheGold/p/6254255.html

 

在這個題目中原做法是他們的題目次數儲存在陣列中,後每一次查詢時列舉,時間複雜度為o(N);建立表的時候時間複雜度也為o(N)

操作耗時,採用線段樹能儲存每一個區間的資訊,而不僅僅是單個的資訊,所需時間複雜度為o(log(n))

以下采用Java實現:

import java.util.Scanner;

public class Main {

	static Scanner sc = new Scanner(System.in);

	private Tree[] build(Tree[] trees, int l, int r, int k){
		
		Tree tree = new Tree();
		trees[k] = tree;
		tree.l = l;
		tree.r = r;
		
		if(l==r){
			tree.w = sc.nextInt();
			return trees;
		}
		
		int m = (l+r)/2;
		trees = build(trees, l, m, 2*k);	
		trees = build(trees, m+1, r, 2*k+1);
	    trees[k].w = Math.max( trees[2*k].w,  trees[2*k+1].w);
		return trees;
	
	}
	
	private int queryMaxW(int max,int k,Tree[] trees,int l, int r){
		
		
		int m = -1;
		if(l == trees[k].l && r == trees[k].r){
			m = trees[k].w;
		}
		else{
		
		int mid = (trees[k].l + trees[k].r)/2;
		
		if(l>mid){
			m = queryMaxW(max, k*2+1, trees, l, r);
		}
		else if(r<=mid){
			m = queryMaxW(max, k*2, trees, l, r);
		}
		else {
	        if(l==r&&l==mid)
	        m =  trees[k*2].w;
	        else{
			int m1 =   queryMaxW(max, k*2, trees, l, mid);
			int m2 =   queryMaxW(max, k*2+1, trees, mid+1, r);
			m = m1>m2?m1:m2;     	
	        }
		}
		}
		return max>m?max:m;
	}
	
	public Tree[] updataEle(Tree[] trees, int l, int r, int k, int val){
		
		if(l == trees[k].l && r == trees[k].r ){
			trees[k].w = val;
			return trees;
		}else {
			int mid = (trees[k].l + trees[k].r)/2;
			if(r<=mid){
				trees=updataEle(trees,l,r,k*2,val);
			}
			else if(l>mid){
				trees=updataEle(trees,l,r,k*2+1,val);
			}
			trees[k].w = Math.max(trees[2*k].w,trees[2*k+1].w);
		}
		
		return trees;
	}
	
	public static void main(String[] args){
	    Tree[] trees = new Tree[500003]; 	
		Main main = new Main();
      
    	while(sc.hasNext()){
    		int PN = sc.nextInt();
    		int ON = sc.nextInt();
    		trees = main.build(trees, 1, PN, 1);
    		while(ON-->0){
    			String does = sc.next();
    			
    			
    			if(does.equals("Q")){
    				int l = sc.nextInt();
    				int r = sc.nextInt();
    				int max =  main.queryMaxW(-1, 1, trees, l, r);
    				System.out.println(max);
    			}else if(does.equals("U")){
    				int x = sc.nextInt();
    				int v= sc.nextInt();
    				trees = main.updataEle(trees, x, x, 1, v);
    			}
    		}
    	
    	}
		
	}
}


class Tree{
	public int l,r,w;
	Tree(){
		super();
	}
}