LCA(最近公共祖先)(复杂度:O(log(n))
ll heads[maxn], fa[maxn][30], wei[maxn][30];
ll dep[maxn], vis[maxn];
struct Edge1
{
ll u, v,w, next;
} edges1[maxm];
void add(ll u, ll v, ll w)
{
edges1[++tot].next = heads[u];
edges1[tot].u = u;
edges1[tot].v = v;
edges1[tot].w = w;
heads[u] = tot;
}
ll fd(ll x)
{
if (f[x] == x)
return x;
return f[x] = fd(f[x]);
}
void dfs(ll now, ll fath)
{
vis[now] = 1;
fa[now][0] = fath;
dep[now] = dep[fath] + 1;
for (ll i = heads[now]; i; i = edges1[i].next)
{
ll v = edges1[i].v;
ll w = edges1[i].w;
if (v == fath)
{
continue;
}
wei[v][0] = w;
dfs(v, now);
}
}
ll LCA(ll x, ll y)
{
if (fd(x) != fd(y))
return -1;
if (dep[x] > dep[y])
{
swap(x, y);
}
ll ans = INF;
for (ll i = 22; i >= 0; i--)
{
if (dep[x] <= dep[y] - (1 << i))
{
ans = min(ans, wei[y][i]);
y = fa[y][i];
}
}
// printf("%lld\n",ans);
if (x == y)
return ans;
for (ll i = 22; i >= 0; i--)
{
if (fa[x][i] != fa[y][i])
{
ans = min(ans, wei[x][i]);
ans = min(ans, wei[y][i]);
x = fa[x][i], y = fa[y][i];
}
}
ans = min(ans, min(wei[x][0], wei[y][0]));
return ans;
}
int main()
{
// debug;
scanf("%lld%lld", &n, &m);
for (ll i = 0; i <= n; i++)
{
f[i] = i;
}
for (ll i = 1; i <= n; i++)
{
// printf("!\n");
if (!vis[i])
{
dfs(i, 0);
fa[i][0] = i;
wei[i][0] = INF;
}
}
for (ll i = 1; i <= 22; i++)
{
for (ll j = 1; j <= n; j++)
{
fa[j][i] = fa[fa[j][i - 1]][i - 1];
wei[j][i] = min(wei[j][i - 1], wei[fa[j][i - 1]][i - 1]);
}
}
scanf("%lld", &q);
while (q--)
{
ll x, y;
scanf("%lld%lld", &x, &y);
printf("%lld\n", LCA(x, y));
}
}
ST表
ll arr[arrn][21],n,m,l,r;//arr[i][j]表示,从i位置开始的2^j个数中的最大值,例如arr[i][1]表示的是i位置和i+1位置中两个数的最大值
ll query(ll l,ll r)
{
ll k=log2(r-l+1);
return max(arr[l][k],arr[r-(1<<k)+1][k]);
}
int main()
{
n=read();m=read();//n,m表示数组元素个数,询问次数
for(ll i=1;i<=n;i++) arr[i][0]=read();
for(ll j=1;j<=21;j++)//注意i,j顺序
{
for(ll i=1;i+(1<<j)-1<=n;i++)
{
arr[i][j]=max(arr[i][j-1],arr[i+(1<<(j-1))][j-1]);
}
}
for(ll i=1;i<=m;i++)
{
l=read();r=read();
printf("%lld\n",query(l,r));
}
}