Flying Squirrel Gym - 102091A (RMQ)

https://vjudge.net/contest/351286#problem/A

題意:1~n位置有不同高度的柱子,一直飛鼠只能從一個柱子飛到高度嚴格比它小的柱子;

給定n個柱子的高度 ,m次詢問:1.從一個柱子最多能飛到多少個柱子上,2.從一個柱子到另一個柱子最多能飛多少次

RMQ查詢區間最大值

對於第一種詢問dfs求最多路徑,把相同高的柱子視爲分隔點,相同高的柱子在分隔點之間往下dfs,求出最長路徑

對於第二種詢問,給柱子分層,最高的爲第一層,在它左邊次低的和在他右邊次低的爲第二層,對於兩個柱子之間,若有你最高的柱子還高的柱子,則不可達,路徑長度爲0,否則路徑長度爲兩個柱子的層數之差;

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+9;
int fa[maxn][20],deep[maxn],ans[maxn],h[maxn],n;

int Max(int l,int r)
{
    return h[l]>=h[r]?l:r;
}

void rmq()
{
    for(int i = 1; i<=n; i++)
    {
        fa[i][0] = i;
    }
    for(int j = 1; (1<<j)<=n; j++)
    {
        for(int i = 1; i+(1<<(j-1))<=n; i++)
        {
            fa[i][j] = Max(fa[i][j-1],fa[i+(1<<(j-1))][j-1]);
        }
    }
}

int get_max(int l,int r)
{
    int k = (int)(log(r-l+1)/log(2.0));
    return Max(fa[l][k],fa[r+1-(1<<k)][k]);
}

int dfs(int l,int r,int lev)
{
    if(l>r)
        return -1;
    int now = get_max(l,r);
    deep[now] = lev;
    ans[now] = dfs(l,now-1,lev+1)+1;
    int res = ans[now];
    while(now<r)//對相同高度的柱子分層
    {
        int next = get_max(now+1,r);
        if(h[now]!=h[next])
            break;
        deep[next] = lev;
        int tmp = dfs(now+1,next-1,lev+1)+1;
        ans[now] = max(ans[now],tmp);
        res = max(res,tmp);
        ans[next] = tmp;
        now = next;
    }
    ans[now] = max(ans[now],dfs(now+1,r,lev+1)+1);
    res = max(ans[now],res);
    return res;
}

int main()
{
    int i,j,m,l,r;
    scanf("%d %d",&n,&m);
    for(i = 1; i<=n; i++)
    {
        scanf("%d",&h[i]);
    }
    rmq();
    dfs(1,n,1);
    while(m--)
    {
        scanf("%d %d",&l,&r);
        if(r==0)
        {
            printf("%d\n",ans[l]);
        }
        else
        {
            if(l==r)
                printf("0\n");
            else
            {
                if(h[l]<h[r])
                    swap(l,r);
                int p;
                if(l<r)
                    p = get_max(l+1,r);
                else
                    p = get_max(r,l-1);
                if(h[p]>=h[l])
                    printf("0\n");
                else
                    printf("%d\n",deep[r]-deep[l]);
            }
        }
    }

    return 0;
}

 

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