题意:给出 n n n个数,查询区间用这些数能组成的最大三角形的周长。
题解:由于给出的数最大范围是 1 e 9 1e9 1e9,而我们已经知道,斐波拉契数列中前两项之和等于第三项,这是构不成三角形的。
所以考虑最坏情况,如果区间内的数刚好构成斐波拉契数列,那么最多到第44项就超过了数据范围,因此在44次循环前如果没有答案,即前44项刚好组成斐波拉契数列,那么后面就一定没有答案。
所以用主席树求区间的第1大,第2大,。。。。第k大判断答案合法性,超过44次没出答案直接break掉。``
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x) x&-x;
#define debugint(name,x) printf("%s: %d\n",name,x);
#define debugstring(name,x) printf("%s: %s\n",name,x);
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 2e5+5;
const int mod = 1e9+7;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m;
vector<int>v;
struct node{
int l,r,sum;
}hjt[maxn*40];
int a[maxn],rt[maxn],cnt;
int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
void insert(int l,int r,int pre,int &now,int p){
hjt[++cnt] = hjt[pre];
now = cnt;
hjt[now].sum++;
if(l == r) return;
int mid = (l+r)>>1;
if(p <= mid) insert(l,mid,hjt[pre].l,hjt[now].l,p);
else insert(mid+1,r,hjt[pre].r,hjt[now].r,p);
}
int query(int l,int r,int L,int R,int k){
if(l == r) return l;
int tmp = hjt[hjt[R].l].sum - hjt[hjt[L].l].sum;
int mid = (l+r)>>1;
if(k <= tmp) return query(l,mid,hjt[L].l,hjt[R].l,k);
else return query(mid+1,r,hjt[L].r,hjt[R].r,k-tmp);
}
int main(){
while(~scanf("%d%d",&n,&m)){
v.clear();
mem(rt,0);
for(int i = 1; i <= n; i++){
scanf("%d",&a[i]);
v.push_back(a[i]);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
for(int i = 1; i <= n; i++)
insert(1,v.size(),rt[i-1],rt[i],getid(a[i]));
int l,r;
while(m--){
scanf("%d%d",&l,&r);
int k = r-l+1;
if(k < 3) puts("-1");
else{
int ok = 0,cnt = 0;
int t = k;
ll x1,x2,x3;
while(k >= 3){
x1 = v[query(1,v.size(),rt[l-1],rt[r],t)-1];
x2 = v[query(1,v.size(),rt[l-1],rt[r],t-1)-1];
x3 = v[query(1,v.size(),rt[l-1],rt[r],t-2)-1];
if(x2+x3>x1){
printf("%lld\n",(ll)(x1+x2+x3));
ok = 1;
break;
}
t--;
k--;
cnt++;
if(cnt >= 45) break;
}
if(!ok) puts("-1");
}
}
}
}