【題解】「USACO 2007 Jan」Balanced Lineup(ST表)

題面

【題目描述】
農夫 JohnJohnN(1<=N<=50,000)N(1 <= N <= 50,000)頭牛總是按同一序列排隊. 有一天,JohnJohn 決定讓一些牛們玩一場飛盤比賽. 他準備找一羣在隊列中位置連續的牛來進行比賽. 但是爲了避免水平懸殊,牛的身高不應該相差太大. JohnJohn準備了Q(1<=Q<=180,000)Q (1 <= Q <= 180,000)個可能的牛的選擇和所有牛的身高 (1<=1 <=身高<=1,000,000<= 1,000,000). 他想知道每一組裏面最高和最低的牛的身高差別.
【輸入】
11行:N,QN,Q
22N+1N+1行:每頭牛的身高
N+2N+2N+Q+1N+Q+1行:兩個整數AABB,表示從AABB的所有牛。(1<=A<=B<=N1<=A<=B<=N
【輸出】
輸出每行一個數,爲最大數與最小數的差
【樣例輸入】

6 3
1
7
3
4
2
5
1 5
4 6
2 2

【樣例輸出】

6
3
0

算法分析

ST表模板題目。
a數組表示N頭牛的身高。
f[i][j]f[i][j]:表示序列a[i]a[i]開始,連續2j2^j個數的最大值。
s[i][j]s[i][j]:表示序列a[i]a[i]開始,連續2j2^j個數的最小值。
狀態轉移方程:
f[i][j]=max(f[i][j1],f[i+2j1][j1])f[i][j]=max(f[i][j-1],f[i+2^{j-1}][j-1])
s[i][j]=minx(s[i][j1],s[i+2j1][j1])s[i][j]=minx(s[i][j-1],s[i+2^{j-1}][j-1])

詢問區間a[x]a[x] ~ a[y]a[y]最大、小值?
找到一個kk,使得[x,x+2k1][y2k+1,y]=[x,y][x , x+2^k-1 ]∪[ y-2^k+1 , y]=[x,y]
需要滿足:2k<=yx+12^k<=y-x+1
k=log2(yx+1)k=log_2(y-x+1)
區間[x,y][x,y]最大值=max(f[x][k],f[y2k1][k])max( f[x][k], f[y-2^k-1][k] )
區間[x,y][x,y]最小值=min(s[x][k],s[y2k1][k])min( s[x][k], s[y-2^k-1][k] )

參考程序

#include<bits/stdc++.h>
#define N 100010
using namespace std;
int f[N][25],s[N][25];
int n,m,x,y;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&f[i][0]);
        s[i][0]=f[i][0];		//初始化
    }
         
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
        {
            f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
            s[i][j]=min(s[i][j-1],s[i+(1<<(j-1))][j-1]); 
        }
    while(m--)
    {
        scanf("%d%d",&x,&y);
        int k=log(y-x+1)/log(2);
        printf("%d\n",max(f[x][k],f[y-(1<<k)+1][k])-min(s[x][k],s[y-(1<<k)+1][k]));
    } 
    return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章