刷水题可耻!

POJ 3264 裸RMQ_ST
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <utility>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))

using namespace std;

int a[50005],N,Q,l,r,f[50005][20],g[50005][20];

void RMQ_ST(int n, int a[])//f[i][j]=max(a[i..i+2^j-1])
{
    for(int i=1; i<=n; i++)
    {
        f[i][0]=a[i];
        g[i][0]=a[i];
    }
    int m=floor(log(n*1.0)/log(2.0));
    for(int j=1; j<=m; j++)
        for(int i=1; i<=n-(1<<j)+1; i++)
        {
            f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
            g[i][j]=min(g[i][j-1],g[i+(1<<(j-1))][j-1]);
        }
}
int main()
{
    scanf("%d%d",&N,&Q);
    for(int i=1; i<=N; i++)
        scanf("%d",&a[i]);
    RMQ_ST(N,a);
    for(int i=0; i<Q; i++)
    {
        scanf("%d%d",&l,&r);
        int k=floor(log((r-l+1)*1.0)/log(2.0));
        printf("%d
",max(f[l][k],f[r-(1<<k)+1][k])-min(g[l][k],g[r-(1<<k)+1][k]));
    }
    return 0;
}
View Code

POJ1330 练下LCA转为RMQ

(顺便吐槽下,毛线在线算法,明明也是预处理再查询的,我要的是边建树边查询!!!)

罢了,查询只要O(1),会快点吧,对于tarjan的O(n+Q)稍微复杂的建边处理

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <utility>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))
#define N 10005

using namespace std;

int into[N],n,t,x,y;
struct Edge
{
    int y,ne;
}e[2*N+1];
int all,be[N];

void add(int x, int y)
{
    e[all].y=y;
    e[all].ne=be[x];
    be[x]=all++;
}

int Eu[2*N],dep[2*N],pos[N],tot;
int f[2*N][25];
bool vis[N];
void dfs(int x, int p)
{
    vis[x]=1;
    Eu[++tot]=x;
    pos[x]=tot;
    dep[tot]=p;
    for(int i=be[x]; i!=-1; i=e[i].ne)
        if(!vis[e[i].y])
        {
            dfs(e[i].y,p+1);
            Eu[++tot]=x;
            dep[tot]=p;
        }
}
void RMQ_ST(int n, int a[])//f[i][j]
{
    int m=floor(log(n*1.0)/log(2.0));
    for(int i=1; i<=n; i++)
        f[i][0]=i;
    for(int j=1; j<=m; j++)
        for(int i=1; i<=n-(1<<j)+1; i++)
        f[i][j]=dep[f[i][j-1]]<dep[f[i+(1<<(j-1))][j-1]]?f[i][j-1]:f[i+(1<<(j-1))][j-1];
}
int rmq(int l, int r)
{
    int k=floor(log((r-l+1)*1.0)/log(2.0));
    return (dep[f[l][k]]<dep[f[r-(1<<k)+1][k]]?f[l][k]:f[r-(1<<k)+1][k]);
}
int lca(int l, int r)
{
    return Eu[rmq(min(pos[l],pos[r]),max(pos[l],pos[r]))];
}

void work(int root, int n)
{
    dfs(root,0);
    RMQ_ST(2*n-1,dep);
    scanf("%d%d",&x,&y);
    printf("%d
",lca(x,y));
}

int main()
{
    scanf("%d",&t);
    while(t--)
    {
        memset(into,0,sizeof(into));
        memset(be,-1,sizeof(be));
        memset(vis,0,sizeof(vis));
        memset(Eu,0,sizeof(Eu));
        memset(dep,0,sizeof(dep));
        all=0;
        scanf("%d",&n);
        for(int i=1; i<=n-1; i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
            into[y]++;
        }
        tot=0;
        for(int i=1; i<=n; i++)
        if(into[i]==0) work(i,n);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Mathics/p/3945970.html