您的位置:首页 > 产品设计 > UI/UE

Range Minimum Query and Lowest Common Ancestor

2008-12-29 22:29 399 查看
RangeMinimumQueryandLowestCommonAncestor
Introduction
Notations
RangeMinimumQuery(RMQ)
TrivialalgorithmsforRMQ
A<O(N),O(sqrt(N))>solution
SparseTable(ST)algorithm
SegmentTrees
LowestCommonAncestor(LCA)
A<O(N),O(sqrt(N))>solution
Anothereasysolutionin<O(NlogN,O(logN)>
ReductionfromLCAtoRMQ
FromRMQtoLCA
An<O(N),O(1)>algorithmfortherestrictedRMQ
Conclusion

Introduction
TheproblemoffindingtheLowestCommonAncestor(LCA)ofapairofnodesinarootedtreehasbeenstudiedmorecarefullyinthesecondpartofthe20thcenturyandnowisfairlybasicinalgorithmicgraphtheory.Thisproblemisinterestingnotonlyforthetrickyalgorithmsthatcanbeusedtosolveit,butforitsnumerousapplicationsinstringprocessingandcomputationalbiology,forexample,whereLCAisusedwithsuffixtreesorothertree-likestructures.HarelandTarjanwerethefirsttostudythisproblemmoreattentivelyandtheyshowedthatafterlinearpreprocessingoftheinputtreeLCA,queriescanbeansweredinconstanttime.Theirworkhassincebeenextended,andthistutorialwillpresentmanyinterestingapproachesthatcanbeusedinotherkindsofproblemsaswell.

Let'sconsideralessabstractexampleofLCA:thetreeoflife.It'sawell-knownfactthatthecurrenthabitantsofEarthevolvedfromotherspecies.Thisevolvingstructurecanberepresentedasatree,inwhichnodesrepresentspecies,andthesonsofsomenoderepresentthedirectlyevolvedspecies.Nowspecieswithsimilarcharacteristicsaredividedintogroups.ByfindingtheLCAofsomenodesinthistreewecanactuallyfindthecommonparentoftwospecies,andwecandeterminethatthesimilarcharacteristicstheyshareareinheritedfromthatparent.

RangeMinimumQuery(RMQ)isusedonarraystofindthepositionofanelementwiththeminimumvaluebetweentwospecifiedindices.WewillseelaterthattheLCAproblemcanbereducedtoarestrictedversionofanRMQproblem,inwhichconsecutivearrayelementsdifferbyexactly1.

However,RMQsarenotonlyusedwithLCA.Theyhaveanimportantroleinstringpreprocessing,wheretheyareusedwithsuffixarrays(anewdatastructurethatsupportsstringsearchesalmostasfastassuffixtrees,butuseslessmemoryandlesscodingeffort).

InthistutorialwewillfirsttalkaboutRMQ.Wewillpresentmanyapproachesthatsolvetheproblem--someslowerbuteasiertocode,andothersfaster.InthesecondpartwewilltalkaboutthestrongrelationbetweenLCAandRMQ.FirstwewillreviewtwoeasyapproachesforLCAthatdon'tuseRMQ;thenshowthattheRMQandLCAproblemsareequivalent;and,attheend,we'lllookathowtheRMQproblemcanbereducedtoitsrestrictedversion,aswellasshowafastalgorithmforthisparticularcase.

Notations
Supposethatanalgorithmhaspreprocessingtimef(n)andquerytimeg(n).Thenotationfortheoverallcomplexityforthealgorithmis<f(n),g(n)>.

WewillnotethepositionoftheelementwiththeminimumvalueinsomearrayAbetweenindicesiandjwithRMQA(i,j).

ThefurthestnodefromtherootthatisanancestorofbothuandvinsomerootedtreeTisLCAT(u,v).

RangeMinimumQuery(RMQ)
GivenanarrayA[0,N-1]findthepositionoftheelementwiththeminimumvaluebetweentwogivenindices.

TrivialalgorithmsforRMQ
Foreverypairofindices(i,j)storethevalueofRMQA(i,j)inatableM[0,N-1][0,N-1].Trivialcomputationwillleadustoan<O(N3),O(1)>complexity.However,byusinganeasydynamicprogrammingapproachwecanreducethecomplexityto<O(N2),O(1)>.Thepreprocessingfunctionwilllooksomethinglikethis:
voidprocess1(intM[MAXN][MAXN],intA[MAXN],intN)
{
inti,j;
for(i=0;i<N;i++)
M[i][i]=i;
for(i=0;i<N;i++)
for(j=i+1;j<N;j++)
if(A[M[i][j-1]]<A[j])
M[i][j]=M[i][j-1];
else
M[i][j]=j;
}

ThistrivialalgorithmisquiteslowandusesO(N2)memory,soitwon'tworkforlargecases.

An<O(N),O(sqrt(N))>solution
Aninterestingideaistosplitthevectorinsqrt(N)pieces.WewillkeepinavectorM[0,sqrt(N)-1]thepositionfortheminimumvalueforeachsection.McanbeeasilypreprocessedinO(N).Hereisanexample:
Nowlet'sseehowcanwecomputeRMQA(i,j).Theideaistogettheoverallminimumfromthesqrt(N)sectionsthatlieinsidetheinterval,andfromtheendandthebeginningofthefirstandthelastsectionsthatintersecttheboundsoftheinterval.TogetRMQA(2,7)intheaboveexampleweshouldcompareA[2],A[M[1]],A[6]andA[7]andgetthepositionoftheminimumvalue.It'seasytoseethatthisalgorithmdoesn'tmakemorethan3*sqrt(N)operationsperquery.

Themainadvantagesofthisapproacharethatistoquicktocode(aplusforTopCoder-stylecompetitions)andthatyoucanadaptittothedynamicversionoftheproblem(whereyoucanchangetheelementsofthearraybetweenqueries).

SparseTable(ST)algorithm
AbetterapproachistopreprocessRMQforsubarraysoflength2kusingdynamicprogramming.WewillkeepanarrayM[0,N-1][0,logN]whereM[i][j]istheindexoftheminimumvalueinthesubarraystartingatihavinglength2j.Hereisanexample:

ForcomputingM[i][j]wemustsearchfortheminimumvalueinthefirstandsecondhalfoftheinterval.It'sobviousthatthesmallpieceshave2j-1length,sotherecurrenceis:

Thepreprocessingfunctionwilllooksomethinglikethis:
voidprocess2(intM[MAXN][LOGMAXN],intA[MAXN],intN)
{
inti,j;
//initializeMfortheintervalswithlength1
for(i=0;i<N;i++)
M[i][0]=i;
//computevaluesfromsmallertobiggerintervals
for(j=1;1<<j<=N;j++)
for(i=0;i+(1<<j)-1<N;i++)
if(A[M[i][j-1]]<A[M[i+(1<<(j-1))][j-1]])
M[i][j]=M[i][j-1];
else
M[i][j]=M[i+(1<<(j-1))][j-1];
}

Oncewehavethesevaluespreprocessed,let'sshowhowwecanusethemtocalculateRMQA(i,j).Theideaistoselecttwoblocksthatentirelycovertheinterval[i..j]andfindtheminimumbetweenthem.Letk=[log(j-i+1)].ForcomputingRMQA(i,j)wecanusethefollowingformula:

So,theoverallcomplexityofthealgorithmis<O(NlogN),O(1)>.

Segmenttrees
ForsolvingtheRMQproblemwecanalsousesegmenttrees.Asegmenttreeisaheap-likedatastructurethatcanbeusedformakingupdate/queryoperationsuponarrayintervalsinlogarithmicaltime.Wedefinethesegmenttreefortheinterval[i,j]inthefollowingrecursivemanner:
·thefirstnodewillholdtheinformationfortheinterval[i,j]
·ifi<jtheleftandrightsonwillholdtheinformationfortheintervals[i,(i+j)/2]and[(i+j)/2+1,j]
NoticethattheheightofasegmenttreeforanintervalwithNelementsis[logN]+1.Hereishowasegmenttreefortheinterval[0,9]wouldlooklike:

Thesegmenttreehasthesamestructureasaheap,soifwehaveanodenumberedxthatisnotaleaftheleftsonofxis2*xandtherightson2*x+1.

ForsolvingtheRMQproblemusingsegmenttreesweshoulduseanarrayM[1,2*2[logN]+1]whereM[i]holdstheminimumvaluepositionintheintervalassignedtonodei.AtthebeginningallelementsinMshouldbe-1.Thetreeshouldbeinitializedwiththefollowingfunction(bandearetheboundsofthecurrentinterval):
voidinitialize(intnode,intb,inte,intM[MAXIND],intA[MAXN],intN)
{
if(b==e)
M[node]=b;
else
{
//computethevaluesintheleftandrightsubtrees
initialize(2*node,b,(b+e)/2,M,A,N);
initialize(2*node+1,(b+e)/2+1,e,M,A,N);
//searchfortheminimumvalueinthefirstand
//secondhalfoftheinterval
if(A[M[2*node]]<=A[M[2*node+1]])
M[node]=M[2*node];
else
M[node]=M[2*node+1];
}
}

Thefunctionabovereflectsthewaythetreeisconstructed.Whencalculatingtheminimumpositionforsomeintervalweshouldlookatthevaluesofthesons.Youshouldcallthefunctionwithnode=1,b=0ande=N-1.

Wecannowstartmakingqueries.Ifwewanttofindthepositionoftheminimumvalueinsomeinterval[i,j]weshouldusethenexteasyfunction:
intquery(intnode,intb,inte,intM[MAXIND],intA[MAXN],inti,intj)
{
intp1,p2;
//ifthecurrentintervaldoesn'tintersect
//thequeryintervalreturn-1
if(i>e||j<b)
return-1;
//ifthecurrentintervalisincludedin
//thequeryintervalreturnM[node]
if(b>=i&&e<=j)
returnM[node];
//computetheminimumpositioninthe
//leftandrightpartoftheinterval
p1=query(2*node,b,(b+e)/2,M,A,i,j);
p2=query(2*node+1,(b+e)/2+1,e,M,A,i,j);
//returnthepositionwheretheoverall
//minimumis
if(p1==-1)
returnM[node]=p2;
if(p2==-1)
returnM[node]=p1;
if(A[p1]<=A[p2])
returnM[node]=p1;
returnM[node]=p2;
}

Youshouldcallthisfunctionwithnode=1,b=0ande=N-1,becausetheintervalassignedtothefirstnodeis[0,N-1].

It'seasytoseethatanyqueryisdoneinO(logN).Noticethatwestopwhenwereachcompletelyin/outintervals,soourpathinthetreeshouldsplitonlyonetime.

Usingsegmenttreeswegetan<O(N),O(logN)>algorithm.Segmenttreesareverypowerful,notonlybecausetheycanbeusedforRMQ.Theyareaveryflexibledatastructure,cansolveeventhedynamicversionofRMQproblem,andhavenumerousapplicationsinrangesearchingproblems.

LowestCommonAncestor(LCA)
GivenarootedtreeTandtwonodesuandv,findthefurthestnodefromtherootthatisanancestorforbothuandv.Hereisanexample(therootofthetreewillbenode1forallexamplesinthiseditorial):

An<O(N),O(sqrt(N))>solution
Dividingourinputintoequal-sizedpartsprovestobeaninterestingwaytosolvetheRMQproblem.ThismethodcanbeadaptedfortheLCAproblemaswell.Theideaistosplitthetreeinsqrt(H)parts,wereHistheheightofthetree.Thus,thefirstsectionwillcontainthelevelsnumberedfrom0tosqrt(H)-1,thesecondwillcontainthelevelsnumberedfromsqrt(H)to2*sqrt(H)-1,andsoon.Hereishowthetreeintheexampleshouldbedivided:

Now,foreachnode,weshouldknowtheancestorthatissituatedonthelastleveloftheuppernextsection.WewillpreprocessthisvaluesinanarrayP[1,MAXN].HereishowPshouldlooklikeforthetreeintheexample(forsimplity,foreverynodeiinthefirstsectionletP[i]=1):

Noticethatforthenodessituatedonthelevelsthatarethefirstonesinsomesections,P[i]=T[i].WecanpreprocessPusingadepthfirstsearch(T[i]isthefatherofnodeiinthetree,nris[sqrt(H)]andL[i]isthelevelofthenodei):
voiddfs(intnode,intT[MAXN],intN,intP[MAXN],intL[MAXN],intnr){
intk;
//ifnodeissituatedinthefirst
//sectionthenP[node]=1
//ifnodeissituatedatthebeginning
//ofsomesectionthenP[node]=T[node]
//ifnoneofthosetwocasesoccurs,then
//P[node]=P[T[node]]
if(L[node]<nr)
P[node]=1;
else
if(!(L[node]%nr))
P[node]=T[node];
else
P[node]=P[T[node]];
foreachsonkofnode
dfs(k,T,N,P,L,nr);
}

Now,wecaneasilymakequeries.ForfindingLCA(x,y)wewewillfirstfindinwhatsectionitlays,andthentriviallycomputeit.Hereisthecode:
intLCA(intT[MAXN],intP[MAXN],intL[MAXN],intx,inty)
{
//aslongasthenodeinthenextsectionof
//xandyisnotonecommonancestor
//wegetthenodesituatedonthesmaller
//levercloser
while(P[x]!=P[y])
if(L[x]>L[y])
x=P[x];
else
y=P[y];
//nowtheyareinthesamesection,sowetriviallycomputetheLCA
while(x!=y)
if(L[x]>L[y])
x=T[x];
else
y=T[y];
returnx;
}

Thisfunctionmakesatmost2*sqrt(H)operations.Usingthisapproachwegetan<O(N),O(sqrt(H))>algorithm,whereHistheheightofthetree.IntheworstcaseH=N,sotheoverallcomplexityis<O(N),O(sqrt(N))>.Themainadvantageofthisalgorithmisquickcoding(anaverageDivision1codershouldn'tneedmorethan15minutestocodeit).

Anothereasysolutionin<O(NlogN,O(logN)>
Ifweneedafastersolutionforthisproblemwecouldusedynamicprogramming.First,let'scomputeatableP[1,N][1,logN]whereP[i][j]isthe2j-thancestorofi.Forcomputingthisvaluewemayusethefollowingrecursion:

Thepreprocessingfunctionshouldlooklikethis:
voidprocess3(intN,intT[MAXN],intP[MAXN][LOGMAXN])
{
inti,j;
//weinitializeeveryelementinPwith-1
for(i=0;i<N;i++)
for(j=0;1<<j<N;j++)
P[i][j]=-1;
//thefirstancestorofeverynodeiisT[i]
for(i=0;i<N;i++)
P[i][0]=T[i];
//bottomupdynamicprograming
for(j=1;1<<j<N;j++)
for(i=0;i<N;i++)
if(P[i][j-1]!=-1)
P[i][j]=P[P[i][j-1]][j-1];
}

ThistakesO(NlogN)timeandspace.Nowlet'sseehowwecanmakequeries.LetL[i]bethelevelofnodeiinthetree.WemustobservethatifpandqareonthesamelevelinthetreewecancomputeLCA(p,q)usingameta-binarysearch.So,foreverypowerjof2(betweenlog(L[p])and0,indescendingorder),ifP[p][j]!=P[q][j]thenweknowthatLCA(p,q)isonahigherlevelandwewillcontinuesearchingforLCA(p=P[p][j],q=P[q][j]).Attheend,bothpandqwillhavethesamefather,soreturnT[p].Let'sseewhathappensifL[p]!=L[q].Assume,withoutlossofgenerality,thatL[p]<L[q].Wecanusethesamemeta-binarysearchforfindingtheancestorofpsituatedonthesamelevelwithq,andthenwecancomputetheLCAasdescribedbelow.Hereishowthequeryfunctionshouldlook:
intquery(intN,intP[MAXN][LOGMAXN],intT[MAXN],
intL[MAXN],intp,intq)
{
inttmp,log,i;
//ifpissituatedonahigherlevelthanqthenweswapthem
if(L[p]<L[q])
tmp=p,p=q,q=tmp;
//wecomputethevalueof[log(L[p)]
for(log=1;1<<log<=L[p];log++);
log--;
//wefindtheancestorofnodepsituatedonthesamelevel
//withqusingthevaluesinP
for(i=log;i>=0;i--)
if(L[p]-(1<<i)>=L[q])
p=P[p][i];
if(p==q)
returnp;
//wecomputeLCA(p,q)usingthevaluesinP
for(i=log;i>=0;i--)
if(P[p][i]!=-1&&P[p][i]!=P[q][i])
p=P[p][i],q=P[q][i];
returnT[p];
}

Now,wecanseethatthisfunctionmakesatmost2*log(H)operations,whereHistheheightofthetree.IntheworstcaseH=N,sotheoverallcomplexityofthisalgorithmis<O(NlogN),O(logN)>.Thissolutioniseasytocodetoo,andit'sfasterthanthepreviousone.

ReductionfromLCAtoRMQ
Now,let'sshowhowwecanuseRMQforcomputingLCAqueries.Actually,wewillreducetheLCAproblemtoRMQinlineartime,soeveryalgorithmthatsolvestheRMQproblemwillsolvetheLCAproblemtoo.Let'sshowhowthisreductioncanbedoneusinganexample:

clicktoenlargeimage

NoticethatLCAT(u,v)istheclosestnodefromtherootencounteredbetweenthevisitsofuandvduringadepthfirstsearchofT.So,wecanconsiderallnodesbetweenanytwoindicesofuandvintheEulerTourofthetreeandthenfindthenodesituatedonthesmallestlevelbetweenthem.Forthis,wemustbuildthreearrays:
·E[1,2*N-1]-thenodesvisitedinanEulerTourofT;E[i]isthelabelofi-thvisitednodeinthetour
·L[1,2*N-1]-thelevelsofthenodesvisitedintheEulerTour;L[i]isthelevelofnodeE[i]
·H[1,N]-H[i]istheindexofthefirstoccurrenceofnodeiinE(anyoccurrencewouldbegood,soit'snotbadifweconsiderthefirstone)
AssumethatH<H[v](otherwiseyoumustswapuandv).It'seasytoseethatthenodesbetweenthefirstoccurrenceofuandthefirstoccurrenceofvareE[H[u]...H[v]].Now,wemustfindthenodesituatedonthesmallestlevel.Forthis,wecanuseRMQ.So,LCAT(u,v)=E[RMQL(H[u],H[v])](rememberthatRMQreturnstheindex).HereishowE,LandHshouldlookfortheexample:

clicktoenlargeimage

NoticethatconsecutiveelementsinLdifferbyexactly1.

FromRMQtoLCA
WehaveshownthattheLCAproblemcanbereducedtoRMQinlineartime.HerewewillshowhowwecanreducetheRMQproblemtoLCA.ThismeansthatweactuallycanreducethegeneralRMQtotherestrictedversionoftheproblem(whereconsecutiveelementsinthearraydifferbyexactly1).Forthisweshouldusecartesiantrees.

ACartesianTreeofanarrayA[0,N-1]isabinarytreeC(A)whoserootisaminimumelementofA,labeledwiththepositioniofthisminimum.TheleftchildoftherootistheCartesianTreeofA[0,i-1]ifi>0,otherwisethere'snochild.TherightchildisdefinedsimilaryforA[i+1,N-1].NotethattheCartesianTreeisnotnecessarilyuniqueifAcontainsequalelements.Inthistutorialthefirstappearanceoftheminimumvaluewillbeused,thustheCartesianTreewillbeunique.It'seasytoseenowthatRMQA(i,j)=LCAC(i,j).

Hereisanexample:

NowweonlyhavetocomputeC(A)inlineartime.Thiscanbedoneusingastack.Atthebeginningthestackisempty.WewilltheninserttheelementsofAinthestack.Atthei-thstepA[i]willbeaddednexttothelastelementinthestackthathasasmallerorequalvaluetoA[i],andallthegreaterelementswillberemoved.TheelementthatwasinthestackonthepositionofA[i]beforetheinsertionwasdonewillbecometheleftsonofi,andA[i]willbecometherightsonofthesmallerelementbehindhim.Ateverystepthefirstelementinthestackistherootofthecartesiantree.It'seasiertobuildthetreeifthestackwillholdtheindexesoftheelements,andnottheirvalue.

Hereishowthestackwilllookateachstepfortheexampleabove:

StepStackModificationsmadeinthetree
000istheonlynodeinthetree.
1011isaddedattheendofthestack.Now,1istherightsonof0.
2022isaddednextto0,and1isremoved(A[2]<A[1]).Now,2istherightsonof0andtheleftsonof2is1.
33A[3]isthesmallestelementinthevectorsofar,soallelementsinthestackwillberemovedand3willbecometherootofthetree.Theleftchildof3is0.
4344isaddednextto3,andtherightsonof3is4.
53455isaddednextto4,andtherightsonof4is5.
634566isaddednextto5,andtherightsonof5is6.
7345677isaddednextto6,andtherightsonof6is7.
8388isaddednextto3,andallgreaterelementsareremoved.8isnowtherightchildof3andtheleftchildof8is4.
93899isaddednextto8,andtherightsonof8is9.
NotethateveryelementinAisonlyaddedonceandremovedatmostonce,sothecomplexityofthisalgorithmisO(N).Hereishowthetree-processingfunctionwilllook:
voidcomputeTree(intA[MAXN],intN,intT[MAXN])
{
intst[MAXN],i,k,top=-1;
//westartwithanemptystack
//atstepiweinsertA[i]inthestack
for(i=0;i<N;i++)
{
//computethepositionofthefirstelementthatis
//equalorsmallerthanA[i]
k=top;
while(k>=0&&A[st[k]]>A[i])
k--;
//wemodifythetreeasexplainedabove
if(k!=-1)
T[i]=st[k];
if(k<top)
T[st[k+1]]=i;
//weinsertA[i]inthestackandremove
//anybiggerelements
st[++k]=i;
top=k;
}
//thefirstelementinthestackistherootof
//thetree,soithasnofather
T[st[0]]=-1;
}

An<O(N),O(1)>algorithmfortherestrictedRMQ
NowweknowthatthegeneralRMQproblemcanbereducedtotherestrictedversionusingLCA.Here,consecutiveelementsinthearraydifferbyexactly1.Wecanusethisandgiveafast<O(N),O(1)>algorithm.FromnowwewillsolvetheRMQproblemforanarrayA[0,N-1]where|A[i]-A[i+1]|=1,i=[1,N-1].WetransformAinabinaryarraywithN-1elements,whereA[i]=A[i]-A[i+1].It'sobviousthatelementsinAcanbejust+1or-1.NoticethattheoldvalueofA[i]isnowthesumofA[1],A[2]..A[i]plustheoldA[0].However,wewon'tneedtheoldvaluesfromnowon.

TosolvethisrestrictedversionoftheproblemweneedtopartitionAintoblocksofsizel=[(logN)/2].LetA'[i]betheminimumvalueforthei-thblockinAandB[i]bethepositionofthisminimumvalueinA.BothAandBareN/llong.Now,wepreprocessA'usingtheSTalgorithmdescribedinSection1.ThiswilltakeO(N/l*log(N/l))=O(N)timeandspace.AfterthispreprocessingwecanmakequeriesthatspanoverseveralblocksinO(1).Itremainsnowtoshowhowthein-blockqueriescanbemade.Notethatthelengthofablockisl=[(logN)/2],whichisquitesmall.Also,notethatAisabinaryarray.Thetotalnumberofbinaryarraysofsizelis2l=sqrt(N).So,foreachbinaryblockofsizelweneedtolockupinatablePthevalueforRMQbetweeneverypairofindices.ThiscanbetriviallycomputedinO(sqrt(N)*l2)=O(N)timeandspace.ToindextableP,preprocessthetypeofeachblockinAandstoreitinarrayT[1,N/l].Theblocktypeisabinarynumberobtainedbyreplacing-1with0and+1with1.

Now,toanswerRMQA(i,j)wehavetwocases:
·iandjareinthesameblock,soweusethevaluecomputedinPandT
·iandjareindifferentblocks,sowecomputethreevalues:theminimumfromitotheendofi'sblockusingPandT,theminimumofallblocksbetweeni'sandj'sblockusingprecomputedqueriesonA'andtheminimumfromthebeginingofj'sblocktoj,againusingTandP;finallyreturnthepositionwheretheoverallminimumisusingthethreevaluesyoujustcomputed.
Conclusion
RMQandLCAarestronglyrelatedproblemsthatcanbereducedonetoanother.Manyalgorithmscanbeusedtosolvethem,andtheycanbeadaptedtootherkindofproblemsaswell.

Herearesometrainingproblemsforsegmenttrees,LCAandRMQ:

SRM310->[u]FloatingMedian

http://acm.pku.edu.cn/JudgeOnline/problem?id=1986
http://acm.pku.edu.cn/JudgeOnline/problem?id=2374
http://acmicpc-live-archive.uva.es/nuevoportal/data/problem.php?p=2045
http://acm.pku.edu.cn/JudgeOnline/problem?id=2763
http://www.spoj.pl/problems/QTREE2/
http://acm.uva.es/p/v109/10938.html
http://acm.sgu.ru/problem.php?contest=0&problem=155

References
-"TheoreticalandPracticalImprovementsontheRMQ-Problem,withApplicationstoLCAandLCE"[PDF]byJohannesFischerandVolkerHeunn
-"TheLCAProblemRevisited"[PPT]byMichaelA.BenderandMartinFarach-Colton-averygoodpresentation,idealforquicklearningofsomeLCAandRMQaproaches
-"Fasteralgorithmsforfindinglowestcommonancestorsindirectedacyclicgraphs"[PDF]byArturCzumaj,MiroslavKowalukandAndrzejLingas
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: