这题本身用到了一个结论,具体结论可以参考我的博客 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; }