Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1460 Accepted Submission(s): 344
Problem Description
sticks are arranged in a row, and their lengths are .
There are querys. For -th of them, you can only use sticks between -th to -th. Please output the maximum circumference of all the triangles that you can make with these sticks, or print denoting no triangles you can make.
Input
There are multiple test cases.
Each case starts with a line containing two positive integers .
The second line contains integers, the -th integer of them showing the length of the -th stick.
Then follow lines. -th of them contains two integers , meaning that you can only use sticks between -th to -th.
It is guaranteed that the sum of s and the sum of s in all test cases are both no larger than .
Output
For each test case, output lines, each containing an integer denoting the maximum circumference.
Sample Input
5 3 2 5 6 5 2 1 3 2 4 2 5
Sample Output
13 16 16
给出n个数,给m次查询,每查询,l,r区间,问区间内选三个值能组成三角形的最大周长是多少。
维护区间内前K大,只需要枚举前46大左右就可以。先取第一大和第二大第三大,比较,若不能构成三角形,那么第二大,第三大,第四大在作比较.理由:若找前46个都不能找到三角形,那么前46个数至少符合Fibonacci数的递增方式,当达到n=46左右的Fibonacci数时就已经超出题目给的范围了。证毕。。。
#include
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m,sum[40*N],ls[40*N],rs[40*N],rt[N],sz,k,cnt;
ll a[N],b[N];
void up(int pre,int &o,int l,int r,int pos)
{
o=++cnt;
ls[o]=ls[pre];
rs[o]=rs[pre];
sum[o]=sum[pre]+1;
if(l==r) return ;
int mid=l+r>>1;
if(pos<=mid)
{
up(ls[pre],ls[o],l,mid,pos);
}
else up(rs[pre],rs[o],mid+1,r,pos);
}
ll qu(int pre,int o,int l,int r)
{
if(l==r) return b[l];
int mid=l+r>>1;
int cmp=sum[rs[o]]-sum[rs[pre]];
//int cmp=sum[ls[o]]-sum[ls[pre]];
if(cmp>=k) return qu(rs[pre],rs[o],mid+1,r);
else
{
k-=cmp;
return qu(ls[pre],ls[o],l,mid);
}
}
void init()
{
cnt=0;
memset(sum,0,sizeof(sum));
memset(ls,0,sizeof(ls));
memset(rs,0,sizeof(rs));
memset(rt,0,sizeof(rt));
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
sz=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++)
{
int j=lower_bound(b+1,b+1+sz,a[i])-b;
up(rt[i-1],rt[i],1,sz,j);
}
while(m--)
{
int ql,qr;
scanf("%d%d",&ql,&qr);
if(qr-ql+1<3) printf("-1\n");
else{
ll val[5],cnt=0;
int tmk=0;k=0;
bool flag=0;
k=1;
tmk=1;
val[++cnt]=qu(rt[ql-1],rt[qr],1,sz);
k=2;
tmk=2;
val[++cnt]=qu(rt[ql-1],rt[qr],1,sz);
while(tmk<=46&&tmk