这题本身用到了一个结论,具体结论可以参考我的博客 https://blog.nowcoder.net/n/c63f99737fbb483aa9d046744f238d71
然后易得题目解法:找到最大的三个能构成三角形的数使其能构成三角形,这个三角形的周长则是题目需求。
这样,问题就转化为了区间查找第k大的数,一共最多要查找45次,所以用主席树查找,总时间复杂度为O(T*q*45*logn),空间复杂度O(n*log^2n)。
以下是代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = (int)1e5+5;
struct node {
int l,r,sum;
} T[MAXN*20];
int n,m,a[MAXN],root[MAXN],cnt,x,y,k,TT,q;
vector<int>v;
int getid(int x) {
return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void updata(int l,int r,int &x,int y,int pos) {
T[++cnt]=T[y],T[cnt].sum++,x=cnt;
if(l==r)return;
int mid=(l+r)/2;
if(mid>=pos)updata(l,mid,T[x].l,T[y].l,pos);
else updata(mid+1,r,T[x].r,T[y].r,pos);
}
int query(int l,int r,int x,int y,int k) {
if(l==r)return l;
int mid=(l+r)/2;
int sum=T[T[y].l].sum-T[T[x].l].sum;
if(sum>=k)return query(l,mid,T[x].l,T[y].l,k);
else return query(mid+1,r,T[x].r,T[y].r,k-sum);
}
vector<ll>ans;
int main() {
while(~scanf("%d%d",&n,&q)) {
v.clear();
cnt=0;
for(int i=1; i<=n; i++)scanf("%d",&a[i]),v.push_back(a[i]),root[i]=0;
sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
for(int i=1; i<=n; i++)updata(1,n,root[i],root[i-1],getid(a[i]));
while(q--) {
int l,r;
scanf("%d%d",&l,&r);
if(r-l+1<3) {
printf("-1\n");
continue;
}
bool flag=0;
ll now=0;
ll fi=(ll)v[query(1,n,root[l-1],root[r],r-l+1)-1];
ll se=(ll)v[query(1,n,root[l-1],root[r],r-l)-1];
for(int i=r-l-1; i>=1; i--) {
ll th=(ll)v[query(1,n,root[l-1],root[r],i)-1];
if(fi<se+th) {
flag=1;
now=fi+se+th;
break;
}
fi=se;
se=th;
}
if(flag)printf("%lld\n",now);
else printf("-1\n");
}
}
return 0;
} 
京公网安备 11010502036488号