RMQ 与 LCA-ST算法

RMQ算法

区间求最值的算法,用区间动态规划(nlogn)预处理,查询O(1)

http://blog.csdn.net/y990041769/article/details/38405063

(POJ 3264)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<sstream>
#define eps 1e-9
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define MAXN 1005
#define MAXM 40005
#define INF 0x3fffffff
#define PB push_back
#define MP make_pair
#define X first
#define Y second
#define clr(x,y) memset(x,y,sizeof(x));
using namespace std;
typedef long long LL;
int i,j,k,n,m,x,y,T,ans,big,cas,num,len;
bool flag;
int a[50005],mm[50005][30],mi[50005][30];

void rmq()
{
    for (int i=1;i<=n;i++)
    {
        mm[i][0]=mi[i][0]=a[i];
    }
    for (int j=1;(1<<j)<=n;j++)
    {
        for (int i=1;i+(1<<j)-1<=n;i++)
        {
            mm[i][j]=max(mm[i][j-1],mm[i+(1<<(j-1))][j-1]);
            mi[i][j]=min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]);
        }
    }
}

int getans(int l,int r)
{
    int k=0;
    while ((1<<(k+1))<=r-l+1) k++;
    int ans1=max(mm[l][k],mm[r-(1<<k)+1][k]);
    int ans2=min(mi[l][k],mi[r-(1<<k)+1][k]);
    return ans1-ans2;
}

int main()
{
    while (~scanf("%d%d",&n,&m))
    {
        clr(mm,0);clr(mi,0);
        for (i=1;i<=n;i++) scanf("%d",&a[i]);
        rmq();
        for (i=1;i<=m;i++)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            printf("%d\n",getans(l,r));
        }
    }

    return 0;
}

 

 

大概看了看求LCA的ST算法,其思路很简单,就是树形转线性,

如果求a与b的最近公共祖先,就是确定first[a]~first[b]中深度最小的点,即求区间最小值,用RMQ维护即可。

http://blog.csdn.net/y990041769/article/details/40887469

 

hdu2586

#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<sstream>
#define eps 1e-9
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define MAXN 80005
#define MAXM 80005
#define INF 0x3fffffff
#define PB push_back
#define MP make_pair
#define X first
#define Y second
#define clr(x,y) memset(x,y,sizeof(x));
using namespace std;
typedef long long LL;
int i,j,k,n,m,x,y,T,ans,big,cas,num,len;
bool flag;

int edge,head[MAXN],id[MAXN],dir[MAXN],first[MAXN],R[MAXN],vis[MAXN],tot;
int dp[MAXN][25];
struct edgenode
{
    int to,next,w;
} G[MAXM];

void add_edge(int x,int y,int w)
{
    G[edge].to=y;
    G[edge].w=w;
    G[edge].next=head[x];
    head[x]=edge++;
}

void dfs(int u,int dep)
{
    vis[u]=true;id[++tot]=u;
    first[u]=tot;R[tot]=dep;
    for (int i=head[u];i!=-1;i=G[i].next)
    {
        int v=G[i].to;
        if (!vis[v])
        {
            int w=G[i].w;
            dir[v]=dir[u]+w;
            dfs(v,dep+1);
            id[++tot]=u; R[tot]=dep;
        }
    }
}

void ST(int n)
{
    for (int i=1;i<=n;i++)
    {
        dp[i][0]=i;
    }
    for (int j=1;(1<<j)<=n;j++)
    {
        for (int i=1;i+(1<<j)-1<=n;i++)
        {
            int a=dp[i][j-1],b=dp[i+(1<<(j-1))][j-1];
            if (R[a]<R[b]) dp[i][j]=a; else dp[i][j]=b;
        }
    }
}

int RMQ(int l,int r)
{
    int k=0;
    while ((1<<(k+1))<=r-l+1) k++;
    int a=dp[l][k],b=dp[r-(1<<k)+1][k];
    return R[a]<R[b]?a:b;
}

int LCA(int u,int v)
{
    int x=first[u],y=first[v];
    if (x>y) swap(x,y);
    return id[RMQ(x,y)];
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(head,-1,sizeof(head));
        edge=0;tot=0;
        scanf("%d%d",&n,&m);
        for (i=1;i<n;i++)
        {
            int x,y,d;
            scanf("%d%d%d",&x,&y,&d);
            add_edge(x,y,d);
            add_edge(y,x,d);
        }
        memset(vis,0,sizeof(vis));
        dfs(1,1);
        ST(2*n-1);
        for (i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            int lca=LCA(u,v);
            printf("%d\n",dir[u]+dir[v]-2*dir[lca]);
        }
    }
    return 0;
}

 

posted @ 2015-08-02 21:24  zhyfzy  阅读(222)  评论(0编辑  收藏  举报