【最小区间问题】 RQM 和 线段树
来源:互联网 发布:企业邮箱域名申请 编辑:程序博客网 时间:2024/05/17 00:14
范围最小值问题,利用进行预处理可以做到nlogn的处理和1的查询。
#include<cstdio>#include<cstring>#include<iostream>#include<stack>#include<map>#include<vector>#include<queue>#include<set>#include<cmath>#include<algorithm>using namespace std;typedef long long LL;typedef unsigned long long ULL;#define MAXD (1 << 10)#define MAX_SIZE 1000 + 10int d[MAXD][MAXD];void RMQ_init(const vector<int>&A){ int n = A.size(); for(int i = 0 ; i < n ; i++) d[i][0] = A[i]; for(int j = 1 ; (1 << j) < n ; j++) for(int i = 0 ; i + (1 << 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 n; vector<int>arr; scanf("%d",&n); for(int i = 0 ; i < n ; i++){ int t; scanf("%d",&t); arr.push_back(t); } RMQ_init(arr); int l,r; while(scanf("%d%d",&l,&r) != EOF){ int ans = RMQ(l,r); printf("The min number in (%d,%d) is %d\n",l,r,ans); }}利用线段树实现RQM,可以做到一遍查询一遍进行改点。
查询说白了就是顺着结点不断往下分区间,当当前的区间被包含在[ql,q2](所求最小值的所在区间)的时候,进行return。
插入的时候更简单了,将A[p] = v,那么不断的往下分区间,知道区间 L = R (也就是 L = R = p)的时候return
#include <vector>#include <list>#include <map>#include <string>#include <set>#include <cstring>#include <deque>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;typedef long long LL;typedef unsigned long long ULL;#define maxd 1 << 10#define INF 1 << 30int minv[maxd];int v,p;int ql,qr; /*查询[ql,qr]区间内的最小值*/int query(int o,int L,int R){ int M = L + (R - L) / 2,ans = INF; if(ql <= L && R <= qr) return minv[o]; else if(ql <= M) ans = min(ans,query(o * 2 , L ,M)); else if(M < qr) ans = min(ans,query(o * 2 + 1,M + 1, R)); return ans;}void update(int o,int L,int R){ /*我们修改A[p] = v,o代表当前的结点,L,R代表当前结点的区间范围*/ int M = L + (R - L)/2; if(L == R) minv[o] = v; else{ if(p <= M) /*如果这个点在左子树区间*/ update(o * 2,L,M); else update(o * 2 + 1,M + 1,R); minv[o] = min(minv[o * 2],minv[o * 2 + 1]); }}int main(){ int n,m; scanf("%d",&n); for(int i = 0 ; i < n ; i++){ p = i + 1; scanf("%d",&v); update(1,1,n); } char str[10]; while(scanf("%s",str) != EOF){ if(str[0] == 'A'){ scanf("%d%d",&p,&v); update(1,0,n); } else { scanf("%d%d",&ql,&qr); int ans = query(1,1,n); printf("%d\n",ans); } } return 0;}
0 0
- 【最小区间问题】 RQM 和 线段树
- noip2012 借教室 (线段树区间减、区间最小)
- 区间树和线段树
- 线段树区间和最大值
- 最小和 --- 求一类数字区间问题
- 线段树-区间单个点更新-区间和-区间最大
- poj3171(线段树区间覆盖最小代价)
- poj 3264 线段树/RMQ(区间最大减最小)
- 数据结构--线段树--区间涂色问题
- 线段树+RMQ区间最值问题
- 线段树解决区间覆盖问题
- 【线段树】浅谈区间问题(1)
- 【线段树】浅谈区间问题(2)
- 【线段树】浅谈区间问题3
- 线段树的区间合并问题
- poj2528&&zoj1610 线段树区间染色问题
- 线段树求解区间值问题
- Tunnel Warfare(线段树区间合并问题)
- linux_wait()与僵尸进程
- hdu 2079 多重背包
- hdu 2111 多重背包
- 13级中欧企业联合大学P-MBA开班
- 算法跨语言/*从一维数组100个数据中选出最大10个数的下标及最小6个数的下标*/
- 【最小区间问题】 RQM 和 线段树
- ADO.NET之3-Command对象---ShinePans
- python利用wxpython实现ssh连接linux进展
- 图像检索中为什么仍用BOW和LSH
- Eclipse快捷键大全
- hdu 1284 完全背包
- hdu 2602 Bone Collector
- java程序员应该掌握的技能
- asound.conf中生成音频文件的