Reference Links:
http://dongxicheng.org/structure/lca-rmq/
http://blog.csdn.net/y990041769/article/details/40887469
Http://www.cnblogs.com/JVxie/p/4854719.html
http://m.blog.csdn.net/qq_35935435/article/details/54916022
Tarjan Offline algorithm:
What is the Tarjan (offline) algorithm? As the name implies, all queries are resolved once in a single traversal, so their time complexity is O (n+q).
The advantage of the Tarjan algorithm is that it is relatively stable, the time complexity is also more centered, and it is easy to understand.
The following is a detailed introduction to the basic idea of the Tarjan algorithm:
1. Choose a point as the root node, starting at the root node.
2. Traverse the point u all child nodes V, and mark those child nodes V has been visited.
3. If v has a child node, return 2, or the next step.
4. Merge V to U.
5. Look for the point V with the current point you have a query relationship.
6. If V has been visited, then you can confirm that the nearest common ancestor of U and V is the Father Node A that V was merged into.
The traversal requires DFS to traverse, merging two nodes using and checking the set.
The pseudo code is as follows:
Tarjan (U)//Marge and find for and look up merge functions and lookup functions { for each (u,v ) // Access to all U-sub-nodes v { Tarjan ( v); // continue traversing down Marge (u,v); // Merge V to u on Mark V has been visited; } for each (u,e) // access all and u have inquiry relationship e { if E was accessed; U,e's nearest public ancestor is find (e); }}
RMQ interval Maximum query algorithm: The ST (Sparse Table) algorithm is a very well known algorithm for on-line processing of RMQ problems, which can be preprocessed in O (nlogn) time and then answered in an O (1) time.
online Algorithm (dfs+st)
①dfs
Let me give you an example.
assume that the traversal order is from right to left, the DFS traversal is available.
DFS traversal sequence f_____________1 3 5 7 5 6 534 3 1 2
Depth Sequence Deep______________1 2 3 4 3 4 323 2 1 2
Node first occurrence position ______1 12 2 9 3 6 4
For the two-node LCA, it is the node with the least depth of the first occurrence. It can then be transformed into a RMQ problem, looking for the minimum value in a range. So the ST algorithm is used to solve the problem.
According to an example, if you ask for LCA (4,7), it is equivalent to RMQ (4,7). First[4]=9,first[7]=4. In the depth sequence the interval (4,9) is 4 3 4 3 2 3, and the depth of the nearest public ancestor is the smallest 2 in this interval. The depth is then iterated into the traversal sequence to get the LCA (4,7) = 3.
②st
F[I,J] is the minimum value of an element with a length of 2^j starting with subscript i. So the state transfer equation isf[i,j]=min (f[i,j-1],f[i+2^ (j-1), j-1])。
③ Query
If you want to query the minimum value of [m,n], first find the largest k. Make K meet 2^k<= (n-m+1). So we can divide [m,n] into two (partially overlapping) lengths of 2^k:[M,m+2^k-1],[n-2^k+1,n]; F[M,K] is the minimum value of f[m,m+2^k-1], F[n-2^k+1,k] is the minimum value of [n-2^k+1,n]. State transition equation:RMQ (i,j) =min (F[m,k],f[n-2^k+1,k]);
now take a look at the example & code.
LZOI2225 Recent public ancestor
Title Description
Title, given a tree with a root, requests a common ancestor that is directly closest to the specified two points.
input
The first line contains three positive integers n, q, S, respectively, representing the number of nodes in the tree, the number of queries, and the sequence number of the root node.
The next n-1 line contains two positive integers per line, u, V, indicating that U-nodes and V-nodes have a directly connected edge (data guarantees can form a tree).
The next line of Q consists of two positive integers a, B, which indicate the nearest common ancestor that asks for a and B nodes.
Output
The output contains q rows, each containing a positive integer, followed by the result of each query.
#include <iostream>using namespacestd;intn,q,root,u,v,a,b,f[50001],f[50001][ +],first[50001],deep[50001],head[50001],tot;BOOLvis[50001];structe{intv; intu; E () {u=0;}} e[1000001];inten=0;voidDfsintUintDEP) {Vis[u]=1; f[++tot]=u; First[u]=tot; Deep[tot]=DEP; for(inti=head[u];i!=0; i=e[i].u)if(!VIS[E[I].V]) {DFS (E[I].V,DEP+1); f[++tot]=u; Deep[tot]=DEP; }}voidST (intLen) { for(intI=1; i<=len;i++) f[i][0]=i; for(intj=1;(1<<J) <=len;j++) { for(intI=1; i+ (1<<J)-1<=len;i++) { inta=f[i][j-1],b=f[i+ (1<< (J-1))][j-1]; F[I][J]=DEEP[A]<DEEP[B]?a:b; } }}intRMQ (intLintR) { intk=0; while((1<< (k +1)) <r-l+1) k++; inta=f[l][k],b=f[r-(1<<K) +1][k]; returnDEEP[A]<DEEP[B]?a:b;}intLCA (intUintv) { intx=first[u],y=First[v]; if(x>y) Swap (x, y); intres=RMQ (x, y); returnf[res];}voidAddintUintV//The adjacency table store is used here! {en++; E[EN].V=v; E[EN].U=Head[u]; Head[u]=en;}intMain () {CIN>>n>>q>>Root; for(intI=1; i<n;i++) {cin>>u>>v; Add (U,V); Add (V,u); } dfs (Root,1); ST (TOT); for(intI=1; i<=q;i++) {cin>>a>>b; cout<<lca (b) <<Endl; } return 0;}
LCA Online Offline algorithm note