傳送門:scu 3365
前面我也寫過
scu 3365 倍增的解法
scu 3365 st 表的解法
scu 3365 disjkstra 的解法
其實,lca 既然可以用 st 表求 rmq (區間最值)來找,也當然可以用線段樹求區間最值來找啦,也不乏樹狀陣列求區間最值,還有直接遍歷(雖然很慢,但也能求),如果不懂 lca 和區間最小值有啥關係,可以先看 hdu 2586 學習 lca 的st表解法
所以在這裡,線段樹只是起到乙個求區間最值的作用,得出遍歷的序列和 st 表解法一樣。
其實,還是不太好寫的,在這裡,得出訪問的序列 ver 陣列 和這個序列每個點的深度dep 陣列,就是要對這個序列的 dep 陣列進行線段樹的區間查詢。建樹要在一般的建樹上做一下改動
void build( int l , int r , int u )
int mid = ( l + r ) / 2 ;
build( lson ) ;
build( rson ) ;
if( node[2*u] <= node[2*u+1] )
node[u].first = node[2*u].first , node[u].second = node[2*u].second ; // second 記錄的是最值在序列中的位置
else
node[u].first = node[2*u+1].first , node[u].second = node[2*u+1].second ;
}
整棵樹所有的節點,除了記錄區間最值資訊之外,還要記錄這個最值對應在序列上的位置 。
很奇怪,我寫的這個**,在 scu 只要 4ms , 比我寫的倍增還要快,在 hdu 2586 卻超時...... 不懂,這兩題要實現的功能是一樣的
scu 3365
#include using namespace std ;
#define lson l , mid , 2*u
#define rson mid+1 , r , 2*u+1
typedef pairp ;
int n , q , len , curl , curr ;
p node[4*1050|1] ;
int head[1050] , k ;
int dis[1050] ;
int first[1050] ; // 記錄這個點第一次出現的位置
int ver[1050<<1] , dep[1050<<1] , top ; // ver 記錄 2*n-1 序列的點 , r 記錄這些點的位置
struct node e[1050<<1|1] ;
void add( int u , int v , int cost )
void dfs( int u , int depth )
}void build( int l , int r , int u )
int mid = ( l + r ) / 2 ;
build( lson ) ;
build( rson ) ;
if( node[2*u] <= node[2*u+1] )
node[u].first = node[2*u].first , node[u].second = node[2*u].second ;
else
node[u].first = node[2*u+1].first , node[u].second = node[2*u+1].second ;
}p quiry( int l , int r , int u )
int main()
dis[1] = 1 , top = 0 , len = 2*n-1 ;
dfs( 1 , 1 ) ;
build( 1 , len , 1 ) ;
while( q-- )
} return 0 ;
}
SCU 3365 學習 LCA 的倍增做法
第一次接觸lca,是在 scu 3365 模板題,當時我是用 disjkstra 加記憶做的,還不會 lca。後來學習 tarjan 演算法,其實還是深搜,當時處理並記錄,tarjan 用來寫 hdu 2586 還是過得去,但是在 scu 3365 卻一直超時,可能 tarjan 演算法在某些資料上...
線段樹的學習記錄
線段樹的學習記錄 1 區間查詢 詢問某段區間的某些性質 極值 求和 etc 2 區間更新 某些操作影響了某些區間 統一加乙個值 3 三個問題 更新點,查詢區間 更新區間,查詢點 更新區間,查詢區間 例如 乙個長度為n 的陣列a 1 a n 我們每次對該陣列有一些操作 1 修改陣列中某個元素的值 1,...
Hdu 2586 學習 LCA 的 ST 表做法
還是hdu 2586 求一棵樹中任意兩點間距離,學習 st 表。st 表是求區間最值的一種預處理 o nlogn 查詢 o 1 的動態規劃。例如長度為8的序列,12 5 3 20 9 7 4 1 用 dp i j 代表從第 i 個開始 包括第 i 個 往後走 2 j 步,所涵蓋的區間的最值。拿最小值...