Light oj 1082 – Array Queries(區間最小值)

來源:互聯網
上載者:User

題目連結

線段樹解法

#include <stdio.h>#include <algorithm>using namespace std;const int maxn = 100010;struct node{    int l, r, mid, minn;}tree[maxn<<2];int a[maxn];void build(int l, int r, int o){    tree[o].l = l;    tree[o].r = r;    int m = (l+r) >> 1;    tree[o].mid = m;    if (l == r)    {        tree[o].minn = a[l];        return ;    }    build(l, m, o<<1);    build(m+1, r, (o<<1)+1);    tree[o].minn = min(tree[o<<1].minn, tree[(o<<1)+1].minn);}int query(int l, int r, int o){    if (tree[o].l == l && tree[o].r == r)        return tree[o].minn;    if (r <= tree[o].mid)        return query(l, r, o<<1);    else if (l > tree[o].mid)        return query(l, r, (o<<1)+1);    else        return min(query(l, tree[o].mid, o<<1), query(tree[o].mid+1, r, (o<<1)+1));}int main(){    int t, n, m, l, r;    scanf("%d",&t);    for (int k = 1; k <= t; k++)    {        scanf("%d%d",&n, &m);        for (int i = 1; i <= n; i++)            scanf("%d",&a[i]);        build(1, n, 1);        printf("Case %d:\n",k);        while (m--)        {            scanf("%d %d",&l, &r);            printf("%d\n",query(l, r, 1));        }    }    return 0;}

Sparse-Table 演算法    劉汝佳 訓練指南  p197

          ST演算法:先是預先處理部分(構造RMQ數組),DP處理。假設b是所求區間最值的數列,dp[i][j] 表示從i到i+2^j -1中最值(從i開始持續2^j個數)。即dp[i][j]=min{dp[i][j-1],dp[i+2^(j-1)][j-1]},或者dp[i][j]=max{dp[i][j-1],dp[i+2^(j-1)][j-1]},這個過程的複雜度為:O(n(longn))

接著就是查詢最值了,可以通過在O(1)完成查詢。就是將查詢區間[s,v],分成兩個2^k的區間。

這裡只要知道這種演算法即可,因為資料量過大,都編譯不通過,不過思想演算法沒有任何問題。

解題代碼

#include <stdio.h>#include <algorithm>using namespace std;const int maxn = 100010;int a[maxn];int d[maxn][maxn];void rmqinit(int n){    for (int i = 1; i <= n; i++)        d[i][0] = a[i];    for (int j = 1; (1<<j) <= n; j++)    {        for (int i = 1; i+j-1 <= n; i++)            d[i][j] = min(d[i][j-1], d[i+(1<<(j-1))][j-1]);    }}int rmq(int l, int r){    int k = 0;    while ((1<<(k+1)) <= r-l+1) k++;    return min(d[l][k], d[r-(1<<k)+1][k]);}int main(){    int t, n, m, l, r;    scanf("%d",&t);    for (int k = 1; k <= t; k++)    {        scanf("%d%d",&n, &m);        for (int i = 1; i <= n; i++)            scanf("%d",&a[i]);        rmqinit(n);        printf("Case %d:\n",k);        while (m--)        {            scanf("%d %d",&l, &r);            printf("%d\n",rmq(l, r));        }    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.