题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6601

Problem Description
N sticks are arranged in a row, and their lengths are a1,a2,...,aN.

There are Q querys. For i-th of them, you can only use sticks between li-th to ri-th. Please output the maximum circumference of all the triangles that you can make with these sticks, or print −1 denoting no triangles you can make.

 
Input
There are multiple test cases.

Each case starts with a line containing two positive integers N,Q(N,Q≤105).

The second line contains N integers, the i-th integer ai(1≤ai≤109) of them showing the length of the i-th stick.

Then follow Q lines. i-th of them contains two integers li,ri(1≤li≤ri≤N), meaning that you can only use sticks between li-th to ri-th.

It is guaranteed that the sum of Ns and the sum of Qs in all test cases are both no larger than 4×105.

 
Output
For each test case, output Q 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
 
主席树求最大三条边,如果三边能组成三角形即为答案,否则再找第二大第三大第四大的边,一直找到符合的
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 100005
#define ll long long
int T[maxn*],L[maxn*],R[maxn*],sum[maxn*],tot;
ll a[maxn],b[maxn];
inline int update(int pre,int l,int r,int x)
{
int rt=++tot;
L[rt]=L[pre];
R[rt]=R[pre];
sum[rt]=sum[pre]+;
if(l<r)
{
int mid=l+r>>;
if(x<=mid)L[rt]=update(L[pre],l,mid,x);
else R[rt]=update(R[pre],mid+,r,x);
}
return rt;
}
inline int query(int u,int v,int l,int r,int k)
{
if(l>=r)return l;
int x=sum[L[v]]-sum[L[u]],mid=l+r>>;
if(x>=k)return query(L[u],L[v],l,mid,k);
else return query(R[u],R[v],mid+,r,k-x);
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=;i<=n;i++)
{
scanf("%lld",&a[i]);
b[i]=a[i];
}
sort(b+,b++n);
int len=unique(b+,b++n)-b-;
T[]=L[]=R[]=sum[]=tot=;
for(int i=;i<=n;i++)
{
int pos=lower_bound(b+,b++len,a[i])-b;
T[i]=update(T[i-],,len,pos);
}
for(int i=;i<=m;i++)
{
int l,r;
int flag=;
ll ans=;
scanf("%d%d",&l,&r);
for(int i=r-l+;i>=;i--)
{
ll A=b[query(T[l - ],T[r],,len,i)];
ll B=b[query(T[l - ],T[r],,len,i-)];
ll C=b[query(T[l - ],T[r],,len,i-)];
if(B+C>A)
{
flag=;
ans=A+B+C;
break;
}
}
if(flag)printf("%lld\n",ans);
else printf("-1\n");
}
} return ;
}

最新文章

  1. CH Round #72 奇数码问题[逆序对 观察]
  2. SQL基础--ROWNUM伪列
  3. 用FileInputStream读取数据,计算机如何实现将两个字节拼接成中文的?
  4. Unity 状态转化机器
  5. 循环日期的shell
  6. Spring 框架获取 datasource对象的方法
  7. CF160D
  8. VxWorks 6.9 内核编程指导之读书笔记 -- POSIX
  9. 第 4 章 多例模式【Multition Pattern】
  10. Contest 20140708 testB dp 组合数
  11. SPOJ 181 - Scuba diver 二维背包
  12. Oracle知识梳理(三)操作篇:SQL基础操作汇总
  13. Django之模板系统
  14. 再回首数据结构—数组(Golang实现)
  15. jS弹出新窗口被拦截的解决方法
  16. vscode &quot;find all references&quot; 提示: no result found.
  17. 配置Arcengine10.1+java开发环境(Eclipse)
  18. Java基础——6种常用类讲解
  19. 《JavaScript面向对象编程指南》
  20. [Java]Get与Post,客户端跳转与服务器端跳转

热门文章

  1. codeforce 381 div2
  2. java 注解(Annotation)
  3. 递归实现深拷贝( 只要学过js递归,看不懂找我包会 )
  4. H3C VLAN显示及维护
  5. linux 从用户空间的 I/O 存取
  6. 2018-2-13-win10-uwp-图标制作器
  7. SSH框架 通用 错误(404,500等)返回页面设置
  8. 服务端CURL请求
  9. opacity兼容性以及存在问题处理
  10. LightOJ - 1265 Island of Survival (概率dp)