平衡阵容

来源:互联网 发布:网络聊天室哪个好 编辑:程序博客网 时间:2024/04/28 19:39
【题目描述】

对于每天挤奶,农民约翰的奶牛(1≤ n ≤50,000)总是以相同的顺序排队。有一天,农夫约翰决定,并组织极限飞盘的游戏与一些奶牛。为了简单起见,他将母牛连续范围从挤奶阵容玩游戏。然而,对于所有的奶牛获得乐趣它们不应相差的高度太大。

农夫约翰已经取得的名单Q(1≤ Q ≤200,000)奶牛和它们的高度(1≤高度≤1,000,000)。对于每个组,他想要您的帮助,以确定在该组中的最短和最高牛之间的高度差。

【输入描述】

1行:两个空格分开的整数,n和Q。 
2行.. n+1:每行包含一个整数,它是牛的高度。
行n+2 .. n+Q+1:两个整数甲和乙(1≤甲≤乙≤n),表示牛的范围区间。
【输出描述】

1 .. Q:每行包含一个整数,它是一个答复,并表示在该范围内的最高和最短牛之间的高度差。

【输入样例】

6 3

1

7

3

4

2

5

1 5

4 6

2 2

【输出样例】

6

3

0

源代码:#include<cstdio>#include<cmath>int m,n,k,i[50001],f1[50001][16],f2[50001][16];int main() //稀疏表(ST表)。{    scanf("%d%d",&n,&m);    for (int a=1;a<=n;a++)    {        scanf("%d",&i[a]);        f1[a][0]=f2[a][0]=i[a];     } //根据f[i][i]初始化初值。    k=floor(log((double)n)/log(2.0));    for (int a=1;a<=k;a++) //DP预处理,f[i,j]表示从第 i 点开始 2^j 个点的最值,表示区间 [i,i+(2^j)-1],则有 [i,j]=[i,j-1]∪[i+2^(j-1),j-1]。       for (int b=1;b+(1<<(a-1))<=n;b++) //防止越界。      {          f1[b][a]=f1[b][a-1]<f1[b+(1<<(a-1))][a-1]?f1[b][a-1]:f1[b+(1<<(a-1))][a-1]; //最小值。          f2[b][a]=f2[b][a-1]>f2[b+(1<<(a-1))][a-1]?f2[b][a-1]:f2[b+(1<<(a-1))][a-1]; //最大值。      }    n=m;    for (int a=1;a<=n;a++) //询问区间最值之差。    {        int t1,t2,s1,s2;        scanf("%d%d",&t1,&t2);        k=floor(log((double)(t2-t1+1))/log(2.0)); //同理进行查询。        s1=f1[t1][k]<f1[t2-(1<<k)+1][k]?f1[t1][k]:f1[t2-(1<<k)+1][k];        s2=f2[t1][k]>f2[t2-(1<<k)+1][k]?f2[t1][k]:f2[t2-(1<<k)+1][k];        printf("%d\n",s2-s1);    }    return 0;}
0 0
原创粉丝点击