poj 2452 Sticks Problem (rmq+二分,需要返回最值位置)

poj2452题目链接

题意:给你一组数a[n],求满足a[i] < a[k] < a[j] (i <= k <= j)的最大的j-i。

思路:大概能想到是rmq,然后想出了一个错误复杂度的错误思路,还直到对拍才发现==

转载一篇题解:poj2452解题报告

收获最大的是:

对于最大值和最小值返回val还是位置的转化竟然可以这样容易!

对于最大值和最小值返回val还是位置的转化竟然可以这样容易!

对于最大值和最小值返回val还是位置的转化竟然可以这样容易!

只要

1int _min(int l,int r)
2{
3    if (a[l]<a[r]) return l;
4    return r;
5}

这样一个函数就可以实现完美转化。。。

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年05月16日 星期一 13时42分56秒
  4File Name :code/poj/2452.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=5E4+7;
 34int n;
 35int a[N];
 36int dp[N][20];
 37int dp2[N][20];
 38
 39
 40int _min(int l,int r)
 41{
 42    if (a[l]<a[r]) return l;
 43    return r;
 44}
 45int _max( int l,int r)
 46{
 47    if (a[l]>a[r]) return l;
 48    else return r;
 49}
 50void max_init()
 51{
 52    for ( int i = 1 ; i <= n ; i++) dp[i][0] = i;
 53
 54    for ( int j = 1 ; (1<<j)<=n ; j++)
 55	for (int i = 1 ; i + (1<<j)-1 <= n ;i++)
 56	    dp[i][j] = _max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
 57}
 58
 59void min_init()
 60{
 61    for ( int i = 1 ;i  <= n ; i++) dp2[i][0] = i;
 62
 63    for ( int j = 1 ; (1<<j)<= n ; j++)
 64	for ( int i = 1 ; i + (1<<j) -1 <= n ; i++)
 65	    dp2[i][j] = _min(dp2[i][j-1],dp2[i+(1<<(j-1))][j-1]);
 66}
 67
 68int rmq_max(int l,int r)
 69{
 70    int k = 0 ;
 71    while (1<<(k+1)<=r-l+1) k++;
 72    return _max(dp[l][k],dp[r-(1<<k)+1][k]);
 73}
 74
 75int rmq_min( int l,int r)
 76{
 77    int k = 0  ;
 78    while (1<<(k+1)<=r-l+1) k++;
 79    return _min(dp2[l][k],dp2[r-(1<<k)+1][k]);
 80}
 81
 82int bin (int x,int l,int r)
 83{
 84    while (l<=r)
 85    {
 86	if (l==r) return l;
 87	int m = (l+r)>>1;
 88	if (a[x]<a[rmq_min(l,m)])
 89	    l = m + 1;
 90	else r = m;
 91    }
 92}
 93void solve()
 94{
 95
 96    int ans = 0;
 97    for ( int i = 1 ; i+ans < n ; i++)
 98    {
 99	int r = bin(i,i+1,n);
100	int k = rmq_max(i,r);
101	if (a[k]>a[i])
102	    ans = max(ans,k-i);
103    }
104    if (ans==0) puts("-1");
105    else printf("%d\n",ans);
106}
107int main()
108{
109	#ifndef  ONLINE_JUDGE 
110	freopen("code/in.txt","r",stdin);
111  #endif
112	 while (scanf("%d",&n)!=EOF)
113	{
114	    for ( int i = 1 ; i <= n ; i++) scanf("%d",&a[i]);
115	    max_init();
116	    min_init();
117
118	    solve();
119	//    cout<<"sadsad"<<endl;
120
121	}
122
123  #ifndef ONLINE_JUDGE  
124  fclose(stdin);
125  #endif
126    return 0;
127}