区间中最大的数RMQ

1174 区间中最大的数

dmax[i][j]表示区间[i,i+j<<2)

 1 #include <iostream>
 2 #include <stdio.h>
 3 using namespace std;
 4 int n,q,dmax[10010][25],a[10010];
 5 void init(){
 6     for(int i = 1; i <= n; i ++){
 7         dmax[i][0] = a[i];
 8     }
 9     for(int j = 1; (1<<j) <= n; j ++){
10         for(int i = 1; i+(1<<j)-1<= n; i ++){
11             dmax[i][j] = max(dmax[i][j-1],dmax[(1<<(j-1))+i][j-1]);
12         }
13     }
14 }
15 int getValue(int l, int r){
16     int k = 0;
17     while(1<<(k+1) <= (r-l+1))k++;
18     return max(dmax[l][k],dmax[r-(1<<k)+1][k]);
19 }
20 int main(){
21     scanf("%d",&n);
22     for(int i = 1; i <= n; i ++){
23         scanf("%d",&a[i]);
24     }
25     init();
26     scanf("%d",&q);
27     while(q--){
28         int l, r;
29         scanf("%d%d",&l,&r);
30         printf("%d\n",getValue(++l,++r));
31     }
32     return 0;
33 }
时间: 2024-11-21 00:02:04

区间中最大的数RMQ的相关文章

51Nod 1174 区间中最大的数(RMQ)

1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 5 using namespace std; 6 const int maxn = 10000 + 5; 7 int a[maxn]; 8 int f[maxn][15]; 9 10 void rmq(int cnt){ 11 memset(f, 0, sizeof(f)); 12 for (int i = 1; i <= cnt

51Nod 1174 区间中最大的数

1174 区间中最大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 描述 给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,最大的数是多少. 例如: 1 7 6 3 1.i = 1, j = 3,对应的数为7 6 3,最大的数为7.(该问题也被称为RMQ问题) Input 第1行:1个数N,表示序列的长度.(2 <= N <= 10000) 第2 - N + 1行:每行1个数,对应序列中的元素.(0 <

51nod 1174 1174 区间中最大的数

题目链接:51nod 1174 1174 区间中最大的数 ST(Sparse Table)算法学习参考博客:http://blog.csdn.net/niushuai666/article/details/6624672 O(nlogn)预处理,O(1)查询 1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 using namespace std; 5 const int N = 10001; 6

(DP ST表 线段树)51NOD 1174 区间中最大的数

给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,最大的数是多少. 例如: 1 7 6 3 1.i = 1, j = 3,对应的数为7 6 3,最大的数为7.(该问题也被称为RMQ问题) Input 第1行:1个数N,表示序列的长度.(2 <= N <= 10000) 第2 - N + 1行:每行1个数,对应序列中的元素.(0 <= S[i] <= 10^9) 第N + 2行:1个数Q,表示查询的数量.(2 <= Q <= 1000

51Nod—1174 区间中最大的数 线段树模版

在大佬们题解的帮助下算是看懂了线段树吧...在这mark下防一手转头就忘. #include<iostream> #include<stdio.h> using namespace std; struct ki { int m,l,r; }tree[40005]; int ans=-1,a[10005]; void build(int n,int l,int r) { tree[n].l=l; tree[n].r=r; if(l==r) { tree[n].m=a[l];retur

CDOJ 1104 求两个数列的子列的交集 查询区间小于A的数有多少个 主席树

求两个数列的子列的交集 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1104 Description 给两个数列A, B,长度分别为n1, n2,保证A中每个元素互不相同,保证B中每个元素互不相同..进行Q次询问,每次查找A[l1...r1]和B[l2..r2]的交集 集合 大小是多少.. 比如 A = {1,2,3,4,5,6,7},B = {7,6,5,4,3,2,1}

nyoj 119士兵杀敌(三)(线段树区间最值查询,RMQ算法)

题目119 题目信息 执行结果 本题排行 讨论区 士兵杀敌(三) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描写叙述 南将军统率着N个士兵,士兵分别编号为1~N,南将军常常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比較,计算出两个人的杀敌数差值.用这样的方法一方面能鼓励杀敌数高的人,还有一方面也算是批评杀敌数低的人,起到了非常好的效果. 所以,南将军常常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少. 如今,请你写一个程

Uva 10765 点双连通求删任意点后剩下图中的连通分量数

题目挂在wustoj上,不知道什么原因不能粘贴链接.. 第一题题号为1314..这题是智力题...换成7的阶乘就可以了.. 代码如下. #include<cstdio> int main() { printf("...............................................................................................\n"); printf("..#................

输出 一维数组中最大的数+数组遍历

1 //将数组中最大的数输出 2 //数组遍历 3 int[] arr = new int[]{2,4,1,6,10,11}; 4 System.out.println("输出一维数组 :"); 5 for(int i=0; i<arr.length;i++) 6 { 7 System.out.print(arr[i]+" "); 8 } 9 10 System.out.println(); 11 12 int max = arr[0]; 13 for(int