题目1544:数字序列区间最小值
时间限制:1秒
内存限制:32 兆
特殊判题:否
提交:1013
解决:194
- 题目描述:
给定一个数字序列,查询任意给定区间内数字的最小值。
输入:
输入包含多组测试用例,每组测试用例的开头为一个整数n(1<=n<=100000),代表数字序列的长度。
接下去一行给出n个数字,代表数字序列。数字在int范围内。
下一行为一个整数t(1<=t<=10000),代表查询的次数。
最后t行,每行给出一个查询,由两个整数表示l、r(1<=l<=r<=n)。
- 输出:
对于每个查询,输出区间[l,r]内的最小值。
- 样例输入:
- 5
3 2 1 4 3
3
1 3
2 4
4 5 - 样例输出:
- 1
- 1
- 3
- RMQ算法:<< 与 >> 位运算的使用
#include<stdio.h> #include<math.h> const int k=17;// 2^16<10^5<2^17 int a[100001]; int f[100001][20]; int n; int min(int a,int b) { return(a<b?a:b); } int rmq() { for (int i=1;i<=n;i++) //初始化 f[i][0]=a[i]; for (int j=1;j<k;j++) for (int i=1;i<=n;i++) if (i+(1<<j)-1<=n) //通过位运算1<<j表示2^j; f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]); return 0; } int query(int l,int r) { int k=(int)(log((double)(r-l+1))/log(2.0)); return(min(f[l][k],f[r-(1<<k)+1][k])); } int main() { while (scanf("%d",&n)!=EOF) { for (int i=1;i<=n;i++) scanf("%d",&a[i]); rmq(); int t; scanf("%d",&t); for (int i=0;i<t;i++) { int l,r; scanf("%d%d",&l,&r); printf("%d\n",query(l,r)); } } return 0; }