题意:

给定一个数列,每次询问一个区间,问这个区间中的值可组成的周长最大的三角形的周长。

题解:

定理1:给定一些值,这些值中组成边长最大的三角形的三条边的大小排名一定是连续的。

证明:假如第k大,第k+1大,第k+2+b(b>0)大的三条边组成了一个边长最大的三角形,那么较小的两条边加起来长度大于第三边,又因为第k+2大的边比第k+2+b大的边长,因此把第k+2+b大的边换成第k+2大的边组成的三角形边长一定比原来大,矛盾。

定理2:如果三角形边长被限制为1e9以内的正整数,那么如果某组值存在周长最大的三角形,一定由前45大的边组成

证明:假如三角形由第44,45,46大的边组成,那么由定理1,前45大的边都组不成三角形,不妨令这个已组成的三角形的周长最小,三边分别为1,1,1,那么,如果要让第k,k+1,k+2大的三条边组不成三角形,必须令第k大的边大于等于后两条边之和。不难推出,第k大的边大于等于Febnacci[46-k],最大的边至少为Feb[45],已经超出1e9的范围,矛盾

有了这两个命题,此题的解法就一目了然,对于每个询问,找出该区间内前45大的值,依次询问排名连续的三个是否能构成三角形。

用主席树维护区间第k大,复杂度O(qlogn*c)    (c=45)

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 1e5 + ;
struct node {
int ls, rs, sum;
//左子树,右子树,该节点值
} ns[MAXN * ]; int ct;
//时间节点
int rt[MAXN * ];
//rt[i]代表a[i]在树上是第几个添加的 void cpy(int& now, int old) {
now = ++ct;
ns[now] = ns[old];
} void pushUp(int& now) {
ns[now].sum = ns[ns[now].ls].sum + ns[ns[now].rs].sum;
} void build(int& now, int l, int r) {
now = ++ct;
ns[now].sum = ;
if (l == r) return;
int m = (l + r) >> ;
build(ns[now].ls, l, m);
build(ns[now].rs, m + , r);
} void update(int& now, int old, int l, int r, int x) {
cpy(now, old);
//在旧树上添加新树
if (l == r) {
ns[now].sum++;
return;
}
int m = (l + r) >> ;
if (x <= m) update(ns[now].ls, ns[old].ls, l, m, x);
else update(ns[now].rs, ns[old].rs, m + , r, x);
pushUp(now);
//向上更新节点权值
} int query(int s, int t, int l, int r, int k) {
if (l == r) return l;
int m = (l + r) >> ;
int cnt = ns[ns[t].ls].sum - ns[ns[s].ls].sum;
//cout << s << " " << t << " " << cnt << endl;
if (k <= cnt) return query(ns[s].ls, ns[t].ls, l, m, k);
return query(ns[s].rs, ns[t].rs, m + , r, k - cnt);
//
} void init(int n) {
ct = ;
build(rt[], , n);
//从头开始建立主席树
} int a[MAXN], b[MAXN];
//b数组是a数组去重后的结果 int solve(int n,int m) { // int n, m;
// scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++) {
scanf("%d", &a[i]);
b[i] = a[i];
}
sort(b + , b + n + );
int sz = unique(b + , b + + n) - b - ;
init(sz);
//初始化树
for (int i = ; i <= n; i++) {
a[i] = lower_bound(b + , b + + sz, a[i]) - b;
//找出当前要添加的节点是b的第几个
update(rt[i], rt[i - ], , sz, a[i]);
//更新这个点
}
/*for (int i = 0; i <= 5 * n; i++) {
printf("%d, rt = %d, ls = %d, rs = %d, sum = %d\n", i, rt[i], ns[rt[i]].ls, ns[rt[i]].rs, ns[rt[i]].sum);
}*/
while (m--) {
int ll,rr;
scanf("%d %d",&ll,&rr);
vector<int> vec;
vec.clear();
for(int i=;i<=min(,rr-ll+);i++){
vec.push_back(b[query(rt[ll-],rt[rr],,sz,rr-ll+-i)]);
// printf("push%d\n",vec[vec.size()-1]);
}
LL ans=-;
for(int i=;i<vec.size();i++){
if(vec[i-]<vec[i-]+vec[i]){
ans=1LL*vec[i-]+vec[i]+vec[i-];
break;
}
}
printf("%lld\n",ans);
// printf("%d\n", b[query(rt[s - 1], rt[t], 1, sz, k)]);
}
return ;
}
int main(){
int n,m;
while(){
int rep=scanf("%d %d",&n,&m);
if(rep==-)break;
else {
// memset()
solve(n,m);
}
}
}

hdu多校第二场1011 (hdu6601) Keen On Everything But Triangle 主席树的更多相关文章

  1. HDU - 6601 Keen On Everything But Triangle 主席树

    Keen On Everything But Triangle 感觉最近多校好多主席树的亚子,但是本人菜得很,还没学过主席树,看着队友写题就只能划水,\(WA\)了还不能帮忙\(debug\),所以深 ...

  2. 2014多校第二场1011 || HDU 4882 ZCC Loves Codefires (贪心)

    题目链接 题意 : 给出n个问题,每个问题有两个参数,一个ei(所要耗费的时间),一个ki(能得到的score).每道问题需要耗费:(当前耗费的时间)*ki,问怎样组合问题的处理顺序可以使得耗费达到最 ...

  3. hdu 6055 : Regular polygon (2017 多校第二场 1011) 【计算几何】

    题目链接 有个结论: 平面坐标系上,坐标为整数的情况下,n个点组成正n边形时,只可能组成正方形. 然后根据这个结论来做. 我是先把所有点按照 x为第一关键字,y为第二关键字 排序,然后枚举向量 (p[ ...

  4. HDU6602 Longest Subarray hdu多校第二场 线段树

    HDU6602 Longest Subarray 线段树 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6602 题意: 给你一段区间,让你求最长的区间使 ...

  5. hdu多校第二场1008(hdu6598) Harmonious Army 最小割

    题意: 一个军队有n人,你可以给他们每个人安排战士或者法师的职业,有m对人有组合技,组合技的信息是a,b,c,代表如果这两个人是两个战士,则组合技威力为a,一个战士一个法师,威力为b,其中b=a/4+ ...

  6. hdu多校第二场 1005 (hdu6595) Everything Is Generated In Equal Probability

    题意: 给定一个N,随机从[1,N]里产生一个n,然后随机产生一个n个数的全排列,求出n的逆序数对的数量,加到cnt里,然后随机地取出这个全排列中的一个非连续子序列(注意这个子序列可以是原序列),再求 ...

  7. hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash

    题意: 找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串 输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数 题解: (回文自动机和回文树是一个东西) 首先用回文 ...

  8. hdu多校第二场 1010 (hdu6600)Just Skip This Problem

    题意: 给你一个数x,允许你多次询问yi,然后回答你x xor yi 是否等于yi,询问尽量少的次数以保证能求出xi是几,求出这样询问次数最少的询问方案数. 结果mod1e6+3 题解: 队友赛时很快 ...

  9. 2019牛客多校第二场 A Eddy Walker(概率推公式)

    2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...

随机推荐

  1. Linux系统的buff/cache缓存清理脚本

    cacheClean.sh #!/bin/bash # 日期: # 作者: 黄慧丰/何鹏举 # 说明: fastdfs所在的linux系统的buffer cache过大, 且并没有有效的自动回收, 因 ...

  2. cocos2D-X 常见49种Action

    bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init( ...

  3. Maven将本地项目打包后引入本地另一个项目

    进入需要打包的文件夹,执行:mvn clean install -X 生成JAR包 打完JAR包后,将maven依赖安装 执行命令: install:install-file -Dfile=E:\co ...

  4. CF 622F (拉格朗日插值)

    传送门 解题思路 比较经典的一道题目.第一种方法是差分,就是假设\(k=3\),我们打一个表. 0 1 9 36 100 225 1 8 27 64 125 7 19 37 61 12 18 24 6 ...

  5. jsonp的原理,应用场景,优缺点

    在开发测试中,难免会在不同域下进行跨域操作,出于安全性考虑,浏览器中的同源策略阻止从一个域上加载的脚本获取或者操作 另一个域下的文档属性,这时需要进行跨域的方式进行解决,如:使用jsonp ,ifra ...

  6. [JZOJ 5810] 简单的玄学

    思路: 就是考虑一个结论 对于\(1<=x<=2^n\),那么\(x\)与\(2^n - x\)中的2的个数相等. 证明: 我们将\(x\)表示成\(2^k*b\),那么\(2^n - x ...

  7. 牛客多校第七场 C Governing sand 线段树

    题意: 有一个树林,树林中不同种类的树有不同的数量,高度,砍伐它们的价格.现在要求砍掉一些树,使得高度最高的树占剩下的树的总数的一半以上,求最小花费. 题解: 用线段树维护不同种类树的信息,叶子节点从 ...

  8. iOS开发UIResponder简介API

    #import <Foundation/Foundation.h> #import <UIKit/UIKitDefines.h> #import <UIKit/UIEve ...

  9. hexo next主题深度优化(七),cdn加速。

    文章目录 注: 正题: 免费cdn 收费cdn 个人博客:https://mmmmmm.me 源码:https://github.com/dataiyangu/dataiyangu.github.io ...

  10. [14]APUE:API for Mysql

    库:/usr/lib64/libmysqlclient.so.#.#... 头文件:/usr/lib64/mysql/mysql.h 一.建立连接 MYSQL *mysql_init(MYSQL *) ...