poj2452 Sticks Problem RMQ问题
2011-09-17 12:01
239 查看
题目大意说:给出一系列的木棒的长度,求出一个最大的区间[x,y],满足所有的len[k]>len[i] && len[k]<len[j] ,i<=k<=j。我看的题目分类说这个题目用RMQ,所有就用了RMQ实现,由于开始的时候我是枚举的所有的区间,所以肯定超时,后来改为从i找出以i开始的最大区间范围,然后在这个范围内求出最大值的下标j,那么j就是从i开始的所有>i且<j的最大区间,枚举采用二分,这样时间复杂度为O(nlogn).
#include <iostream> #include <stdio.h> #include <cmath> const int N=50001; using namespace std; int m ,large [17],smal [17]; inline int get_max(int a,int b) { return a>b?a:b; } inline int get_min(int a,int b) { return a<b?a:b; } void initrmq(int n) { int i,j; for(i=0;i<n;i++) { large[i][0]=i; smal[i][0]=i; } for(j=1;(1<<j)<=n;j++) { for(i=0;i+(1<<j)-1 < n;i++) { if(m[large[i][j-1]] > m[large[i+(1<<(j-1))][j-1]]) large[i][j]=large[i][j-1]; else large[i][j]=large[i+(1<<(j-1))][j-1]; if(m[smal[i][j-1]] < m[smal[i+(1<<(j-1))][j-1]]) smal[i][j]=smal[i][j-1]; else smal[i][j]=smal[i+(1<<(j-1))][j-1]; } } } int querymin(int i,int j) { int k=(int)(log(1.0*(j-i+1))/log(2.0)); if(m[smal[i][k]] < m[smal[j-(1<<k)+1][k]]) return smal[i][k]; return smal[j-(1<<k)+1][k]; } int querymax(int i,int j) { if(i>j) { int tmp=i; i=j; j=tmp; } int k=(int)(log(1.0*(j-i+1))/log(2.0)); if(m[large[i][k]] > m[large[j-(1<<k)+1][k]]) return large[i][k]; return large[j-(1<<k)+1][k]; } //找出以i开头的最大区间范围 int findIdx(int n,int l) { int mid,i=l,j=n-1; while(i+1<=j) { mid=(i+j)>>1; if(querymin(l,mid) == l)//如果现在的区间最小值下标是l,则扩大范围,否则缩小范围 i=mid+1; else j=mid-1; } return j; } int solve(int n) { int i,j,ans=0,k,l,r; l=0; r=n-1; for(i=0;i<n-1;i++) { j=findIdx(n,i); k=querymax(i,j); // cout<<j<<" "<<k<<endl; if(k-i > ans) ans=k-i; } if(ans) return ans; return -1; } int main() { int i,n; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) scanf("%d",&m[i]); memset(large,0,sizeof(large)); memset(smal,0,sizeof(smal)); initrmq(n); int ans=solve(n); printf("%d\n",ans); } return 0; }
相关文章推荐
- POJ 2452 Sticks Problem(RMQ+二分)
- A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。
- poj 3264 RMQ问题 zkw线段树
- poj 2826 An Easy Problem?! (线段相交问题终极版...并不easy)
- Sumdiv&&http://poj.org/problem?id=1845&&约数和问题
- Problem A POJ 1321 棋盘问题(dfs)
- 棋盘问题&&http://poj.org/problem?id=1321
- Balanced Lineup+POJ+RMQ问题
- POJ2019(二维RMQ问题 ST)
- POJ - 2282 - The Counting Problem - (计数问题)
- http://poj.org/problem?id=3984 迷宫问题
- 搜索练习3 /poj.org/problem 3984 迷宫问题/bfs 回溯找路经
- poj 2452(RMQ+二分)
- 【RMQ】POJ 2452
- poj 1330 LCA问题 (LCA问题转化为RMQ || tarjan算法)
- POJ 3264 RMQ问题 用dp解决
- RMQ 问题 POJ 3264 求解任意指定区间内的最小值和最大值
- POJ - 1065 Wooden Sticks(DP 子序列问题)
- http://poj.org/problem?id=3628 背包问题还有一个地方没想明白 直接DFS()
- POJ 2452 Sticks Problem(二分+RMQ)