Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 8623 | Accepted: 2222 |
Description
Input
Output
Sample Input
4 5 4 3 6 4 6 5 4 3
Sample Output
1 -1
Source
//这题对于我来说,难点是这个二分查找、第一次知道原来可以这样二分查找
//求最大的 j-i(j>i) 对于任意的 i<k<j 有Si<k<Sj成立
//先求出离Sj最近,但比Sj大的St位置,然后i就是St~Sj区间最小值了;
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <queue> #define lson l,m,k<<1 #define rson m+1,r,k<<1|1 using namespace std; #define N 50010 struct node { int min,id; int max; }st[N<<2]; int rc[N]; int rid[N<<1]; void up(int &k) { st[k].max=max(st[k<<1].max,st[k<<1|1].max); st[k].min=min(st[k<<1].min,st[k<<1|1].min); } void build(int l,int r,int k) { if(l==r) { scanf("%d",&rc[l]); st[k].max=st[k].min=rc[l]; rid[rc[l]]=l; return ; } int m=(l+r)>>1; build(lson); build(rson); up(k); } int Find_Max(int L,int R,int l,int r,int k) { if(L<=l&&R>=r) return st[k].max; int m=(l+r)>>1,t1=0,t2=0; if(L<=m) t1=Find_Max(L,R,lson); if(R>m) t2=Find_Max(L,R,rson); return max(t1,t2); } int Find_Min(int L,int R,int l,int r,int k) { if(L<=l&&R>=r) return st[k].min; int m=(l+r)>>1,t1=1000000,t2=1000000; if(L<=m) t1=Find_Min(L,R,lson); if(R>m) t2=Find_Min(L,R,rson); return min(t1,t2); } int n; int bf(int R) { int l=1,r=R,m; int temp;R++; while(l<r) { m=(l+r)>>1; temp=Find_Max(m+1,r,1,n,1); if(temp>rc[R]) l=m+1; else r=m; } return l; } int main() { int j,k,t,var; int Max,id; while(scanf("%d",&n)!=EOF) { Max=0; build(1,n,1); j=n; while(j>1) { var=rc[j]; id=bf(j-1); if(rc[id]>rc[j]) k=id+1; else k=id; var=Find_Min(k,j,1,n,1); id=rid[var]; Max=max(j-id,Max); j=id-1; } if(Max) printf("%d\n",Max); else printf("-1\n"); } return 0; }