Uva 11235 RMQ问题
2017-01-18 18:30
393 查看
RMQ:
有一个不变的数组,不停的求一个区间的最小值。
使用倍增的思想优化到logN;
d(i,j) 表示从 i 开始的,长度为2j的一段元素中的最小值。
那么状态转移方程:
d(i,j) = min{ d(i,j-1) , d(i+2j-1,j-1) }
题目链接:https://vjudge.net/contest/146667#problem/B
题意:一个非降序的数组,询问(i,j)中出现次数最多的数值,所对应的出现次数是多少。
分析:
进行游戏编码,value[i] 和count[i] 表示第 i 段对应的数值和出现的次数,
num[i] 表示位置 i 对应的段所在的编号,left[i] 表示 i 位置所在的段的左端点,right[i] 右端点。
那么(L,R)就是分成3个部分。
一个是right[L] - L + 1,R-left[R] + 1,还一个就是RMQ(count,num[L]+1,num[R]-1)。
特殊情况:如果L和R在同一段里面,R-L+1;
Source Code:
View Code
有一个不变的数组,不停的求一个区间的最小值。
使用倍增的思想优化到logN;
d(i,j) 表示从 i 开始的,长度为2j的一段元素中的最小值。
那么状态转移方程:
d(i,j) = min{ d(i,j-1) , d(i+2j-1,j-1) }
题目链接:https://vjudge.net/contest/146667#problem/B
题意:一个非降序的数组,询问(i,j)中出现次数最多的数值,所对应的出现次数是多少。
分析:
进行游戏编码,value[i] 和count[i] 表示第 i 段对应的数值和出现的次数,
num[i] 表示位置 i 对应的段所在的编号,left[i] 表示 i 位置所在的段的左端点,right[i] 右端点。
那么(L,R)就是分成3个部分。
一个是right[L] - L + 1,R-left[R] + 1,还一个就是RMQ(count,num[L]+1,num[R]-1)。
特殊情况:如果L和R在同一段里面,R-L+1;
Source Code:
#include<cstdio> #include<algorithm> #include<vector> using namespace std; const int maxn = 100000 + 5; const int maxlog = 20; // 区间最*大*值 struct RMQ { int d[maxn][maxlog]; void 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] = max(d[i][j-1], d[i + (1<<(j-1))][j-1]); } int query(int L, int R) { int k = 0; while((1<<(k+1)) <= R-L+1) k++; // 如果2^(k+1)<=R-L+1,那么k还可以加1 return max(d[L][k], d[R-(1<<k)+1][k]); } }; int a[maxn], num[maxn], left[maxn], right[maxn]; RMQ rmq; int main() { int n,q; while(scanf("%d%d",&n,&q)==2) { for(int i=0; i<n; i++) scanf("%d",&a[i]); a = a[n-1] + 1; int start = -1; vector<int> count; for(int i=0; i<=n; i++) { if(i==0||a[i]>a[i-1]) { if(i>0) { count.push_back(i-start); for(int j=start;j<i;j++) { num[j] = count.size()-1; left[j] = start; right[j] = i-1; } } start = i; } } rmq.init(count); while(q--) { int L,R,ans; scanf("%d%d",&L,&R); L--; R--; if(num[L]==num[R]) ans = R - L + 1; else { ans = max(R-left[R]+1,right[L]-L+1); if(num[L]+1<num[R]) ans = max(ans,rmq.query(num[L]+1,num[R]-1)); } printf("%d\n",ans); } } return 0; }
View Code
相关文章推荐
- UVA 11235 RMQ问题
- uva 11235 - Frequent values(RMQ问题)
- UVA 11235--Frequent values+RMQ问题
- Frequent Values(UVa 11235) RMQ问题
- Uva 11235 Frequent values 【RMQ问题】
- ST算法解决RMQ问题及UVA 11235题解
- RMQ问题 UVa 11235
- Uva 11235 Frequent values (RMQ问题 STable算法的应用)
- 指南第三章 例题八 UVA 11235 Frequent values(RMQ问题)
- UVA 11235 经典RMQ问题
- UVA - 11235 Frequent values RMQ问题
- UVA 11235 RMQ(范围最小值(最大值)问题):Sprase Table算法
- UVA 11235 Frequent values(RMQ)
- UVA 11235 Frequent values 非递减序列 l r范围内 出现最多的数字次数 RMQ
- uva 11235 RMQ范围最大值
- UVA 11235 Frequent Values ---RMQ
- uva 11235 Frequent values RMQ
- UVA 11235 频繁出现的数值 RMQ
- UVA 11235 Frequent Values ---RMQ
- UVa 11235 RMQ