淺談ST及lca應用

ST

ST就不細講了
直接給代碼,

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int f[MAXN][21],n,m;
int query(int l,int r)
{
	int k=log2(r-l+1);
	return max(f[l][k],f[r-(1<<k)+1][k]);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) f[i][0]=read();
	for (int j=1; j<=21; j++)
	  for (int i=1; i+(1<<j)-1<=n; i++)
	    f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    while (m--)
      {
      	int x,y;
      	scanf("%d%d",&x,&y);
      	printf("%d\n",query(x,y));
      }
}

然後嫌慢的可以常數優化,就是把可能出現的log值和位運算值直接預處理出來然後就可以直接調用了,會快很多。

然後樹上求最近公共祖先問題(lca)
先把樹的dfs序求出來
在這裏插入圖片描述

dfs序可以得出
1 2 4 2 1 3 5 7 5 3 6 8 6 9
記錄一下每個點第一次出現的位置以及深度
然後你要求的兩個點的最近祖先就是這兩個點之間的深度最小的點。
st在這裏主要就是用來找最小的數,和lca並沒有多大關係
這樣做的原理呢
就是兩個點之間深度最小的那個點肯定是這兩個點的祖先,
然後這兩點的比這個祖先深度低的祖先肯定不會出現在這兩個點之間,仔細想想你就明白啦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章