找区间内三条边可组成周长最长的三角形,因为三角形边长关系,最坏情况就是斐波那契数,从1e9按斐波那契数递减,题解上说就44个,所以就暴力找区间内第k,k-1,k-2大数,判断其是否组成三角形
保险开个long long ,根据hdu2665模板写的,那题题意真的问题很大,让我以为模板是找第k大的数,结果却是找第k小的,模板还要稍微改一下,特判当所给区间长度没有三直接输出负一,这里卡了一个小时
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <set>
#include <ctime>
#include <algorithm>
#define eps 1e-14
#define pi acos(-1)
#define ll long long
#define RD T*(rand()*2-RAND_MAX)
#define Drand (long double)rand()/RAND_MAX
#define LINF 1e18
#define INF 0x3f3f3f3f
using namespace std;
const int maxn= 1e5 + 10 ;
const int mod= 1e4 + 7 ;
int tot= 0 ;
int aa[ maxn] , a[ maxn] , L[ maxn* 21 ] , R[ maxn* 21 ] , sum[ maxn* 21 ] , T[ maxn] ;
void build ( int l, int r, int & rt)
{
rt= ++ tot;
sum[ rt] = 0 ;
if ( l== r) return ;
int mid= ( l+ r) >> 1 ;
build ( l, mid, L[ rt] ) ;
build ( mid+ 1 , r, R[ rt] ) ;
}
void update ( int l, int r, int & rt, int pre, int x)
{
rt= ++ tot;
L[ rt] = L[ pre] ;
R[ rt] = R[ pre] ;
sum[ rt] = sum[ pre] + 1 ;
if ( l== r) return ;
int mid= ( l+ r) >> 1 ;
if ( x<= mid) update ( l, mid, L[ rt] , L[ pre] , x) ;
else update ( mid+ 1 , r, R[ rt] , R[ pre] , x) ;
}
int query ( int l, int r, int tl, int tr, int k)
{
if ( l== r) return l;
int mid= ( l+ r) >> 1 ;
int res= sum[ R[ tr] ] - sum[ R[ tl] ] ;
if ( res>= k) query ( mid+ 1 , r, R[ tl] , R[ tr] , k) ;
else query ( l, mid, L[ tl] , L[ tr] , k- res) ;
}
int main ( )
{
int n, m;
while ( ~ scanf ( "%d%d" , & n, & m) ) {
for ( int i= 1 ; i<= n; i++ ) scanf ( "%d" , & aa[ i] ) , a[ i] = aa[ i] ;
sort ( a+ 1 , a+ 1 + n) ;
int num= unique ( a+ 1 , a+ 1 + n) - a- 1 ;
tot= 0 ;
build ( 1 , num, T[ 0 ] ) ;
for ( int i= 1 ; i<= n; i++ ) {
int x= lower_bound ( a+ 1 , a+ 1 + num, aa[ i] ) - a;
update ( 1 , num, T[ i] , T[ i- 1 ] , x) ;
}
while ( m-- ) {
int l, r;
scanf ( "%d%d" , & l, & r) ;
if ( r- l+ 1 < 3 ) {
printf ( "-1\n" ) ;
continue ;
}
int k= 4 , x1, x2, x3;
ll Max= - 1 ;
x1= query ( 1 , num, T[ l- 1 ] , T[ r] , 1 ) ;
x2= query ( 1 , num, T[ l- 1 ] , T[ r] , 2 ) ;
x3= query ( 1 , num, T[ l- 1 ] , T[ r] , 3 ) ;
if ( ( ll) a[ x1] < ( ll) ( a[ x2] + a[ x3] ) ) Max= ( ll) a[ x1] + ( ll) a[ x2] + ( ll) a[ x3] ;
else {
while ( k<= r- l+ 1 ) {
x1= x2;
x2= x3;
x3= query ( 1 , num, T[ l- 1 ] , T[ r] , k) ;
if ( ( ll) a[ x1] < ( ll) ( a[ x2] + a[ x3] ) ) {
Max= ( ll) a[ x1] + ( ll) a[ x2] + ( ll) a[ x3] ;
break ;
}
k++ ;
}
}
printf ( "%lld\n" , Max) ;
}
}
return 0 ;
}