• [2019杭电多校第二场][hdu6601]Keen On Everything But Triangle


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

    题意是说用给定区间内的数字组成周长最大的三角形。

    大致做法就是求区间第1大,第2大和第3大然后判断是否满足,不满足再求第4大,第5大....。

    原本以为复杂度爆炸,结果想想发现最坏的情况只是斐波那契的样子,每个区间也不会很大。

    求区间第i大就套了个主席树

     1 #include <algorithm>
     2 #include<iostream>
     3 #include <cstdio>
     4 #include <vector>
     5 #include <cstring>
     6 #include<queue>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn = 2e5 + 3;
    10 int a[maxn], b[maxn];
    11 int root[maxn], ls[maxn * 20], rs[maxn * 20], cnt;
    12 ll  val[maxn * 20];
    13 void build(int l, int r, int &i) {
    14     i = ++cnt;
    15     val[i] = 0ll;
    16     if (l == r)
    17         return;
    18     int mid = l + r >> 1;
    19     build(l, mid, ls[i]);
    20     build(mid + 1, r, rs[i]);
    21 }
    22 void update(int k, int l, int r, int &i) {
    23     ls[++cnt] = ls[i], rs[cnt] = rs[i], val[cnt] = val[i] + 1;
    24     i = cnt;
    25     if (l == r)
    26         return;
    27     int mid = l + r >> 1;
    28     if (k <= mid)
    29         update(k, l, mid, ls[i]);
    30     else
    31         update(k, mid + 1, r, rs[i]);
    32 }
    33 ll query(int u, int v, int k, int l, int r) {
    34     if (l == r)
    35         return l;
    36     int x = val[ls[v]] - val[ls[u]];
    37     int mid = l + r >> 1;
    38     if (k <= x)
    39         return query(ls[u], ls[v], k, l, mid);
    40     else
    41         return query(rs[u], rs[v], k - x, mid + 1, r);
    42 }
    43 int main() {
    44     int n, m;
    45     while (scanf("%d%d", &n, &m) != EOF) {
    46         cnt = 0;
    47         for (int i = 1; i <= n; i++)
    48             scanf("%d", &a[i]), b[i] = a[i];
    49         sort(b + 1, b + 1 + n);
    50         int k = unique(b + 1, b + 1 + n) - b - 1;
    51         build(1, k, root[0]);
    52         for (int i = 1; i <= n; i++) {
    53             int t = lower_bound(b + 1, b + 1 + k, a[i]) - b - 1;
    54             t++;
    55             root[i] = root[i - 1];
    56             update(t, 1, k, root[i]);
    57         }
    58         for (int i = 1; i <= m; i++) {
    59             int l, r;
    60             scanf("%d%d", &l, &r);
    61             int len = r - l + 1;
    62             if (len < 3) {
    63                 printf("-1
    ");
    64                 continue;
    65             }
    66             ll ans = -1;
    67             ll x = b[query(root[l - 1], root[r], len, 1, k)];
    68             ll y = b[query(root[l - 1], root[r], len - 1, 1, k)];
    69             for (int i = 3; i <= len; i++) {
    70                 ll z = b[query(root[l - 1], root[r], len - i + 1, 1, k)];
    71                 if (x < y + z) {
    72                     ans = x + y + z;
    73                     break;
    74                 }
    75                 else {
    76                     x = y;
    77                     y = z;
    78                 }
    79             }
    80             printf("%lld
    ", ans);
    81         }
    82     }
    83 
    84 }
  • 相关阅读:
    Flink 1.9 实战:使用 SQL 读取 Kafka 并写入 MySQL
    Spring 社区的唯一一个国产开源项目
    使用DynamoShake从dynamodb迁移到mongodb
    1754-I Hate It 线段树(单点替换,区间最值)
    1166-敌兵布阵 线段树(单点增减,区间求和)
    P1078 文化之旅
    P1107 最大整数
    521. [NOIP2010] 引水入城 cogs
    P1137 旅行计划
    P2678 跳石头(二分答案)
  • 原文地址:https://www.cnblogs.com/sainsist/p/11328824.html
Copyright © 2020-2023  润新知