POJ-2823(ST算法 + 滚动数组)

来源:互联网 发布:喜欢 知乎 编辑:程序博客网 时间:2024/06/07 16:11

ST算法是求解RMQ问题最有效的方法之一,核心思想是以nlogn的复杂度递推f(i, 2^j) = min( f(i, 2^(j-1)), f(i + 2^(j-1), 2^(j-1)) ),其中f(i,2*j)表示arr[i, i + 2*j - 1]这个区间内的最小值

由于本题区间是确知的,所以递推时可以使用滚动数组来实现


#include <stdio.h>#define max(a, b) ((a) > (b) ? (a) : (b))#define min(a, b) ((a) < (b) ? (a) : (b))int n, k;int m[1000000], M[1000000];int main(){    int i, j, t;/* input */    scanf("%d %d", &n, &k);    for(i = 0; i < n; ++i){        scanf("%d", &m[i]);        M[i] = m[i];    }/* special judge */    if(k == 1){        printf("%d", m[0]);        for(i = 1; i < n; ++i) printf(" %d", m[i]);        putchar('\n');        printf("%d", m[0]);        for(i = 1; i < n; ++i) printf(" %d", m[i]);        return 0;    }/* create sparse table with rolling array */    k = min(k, n);    for(j = 1; (t = j << 1) < k; j = t){        for(i = 0; i + t <= n; ++i){            m[i] = min(m[i], m[i + j]);            M[i] = max(M[i], M[i + j]);        }    }/* print result */    j = k - j;    printf("%d", min(m[0], m[j]));    for(i = 1; i + k <= n; ++i) printf(" %d", min(m[i], m[i + j]));    putchar('\n');    printf("%d", max(M[0], M[j]));    for(i = 1; i + k <= n; ++i) printf(" %d", max(M[i], M[i + j]));    return 0;}



0 0
原创粉丝点击