Keen On Everything But Triangle
Solving problems
Use the chairman tree to find the k-small interval, first find the maximum value in the interval, then find the second and third... Until three consecutive numbers are found to form a triangle. Because for a group of numbers, if they can't form a triangle, the Fibonacci series is small. Because the range of numbers is within 10 ^ 9, there won't be more than 50 numbers. That is to say, if we query violently, the number of queries won't exceed 50, and we will find the result.
The code is as follows
#include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; inline int read(){ int res = 0, w = 0; char ch = 0; while(!isdigit(ch)){ w |= ch == '-', ch = getchar(); } while(isdigit(ch)){ res = (res << 3) + (res << 1) + (ch ^ 48); ch = getchar(); } return w ? -res : res; } const int N = 100005; int rt[N], cnt; struct T{ int l, r; int lch, rch; int sum; }tree[N << 5]; ll a[N], b[N]; int build(int l, int r) { int p = ++cnt; tree[p].l = l; tree[p].r = r; tree[p].lch = tree[p].rch = tree[p].sum = 0; if(l == r) return p; int mid = (l + r) / 2; tree[p].lch = build(l, mid); tree[p].rch = build(mid + 1, r); return p; } int insert(int k, int x) { int p = ++cnt; tree[p].l = tree[k].l; tree[p].r = tree[k].r; tree[p].lch = tree[k].lch; tree[p].rch = tree[k].rch; tree[p].sum = tree[k].sum + 1; if(tree[k].l == tree[k].r) return p; int mid = (tree[k].l + tree[k].r) / 2; if(x <= mid) tree[p].lch = insert(tree[k].lch, x); else tree[p].rch = insert(tree[k].rch, x); return p; } int query(int k1, int k2, int x) { if(tree[k1].l == tree[k1].r) return tree[k1].l; int l1 = tree[k1].lch; int l2 = tree[k2].lch; if(tree[l2].sum - tree[l1].sum >= x) return query(l1, l2, x); else { x -= tree[l2].sum - tree[l1].sum; return query(tree[k1].rch, tree[k2].rch, x); } } int main() { int n, q; while(scanf("%d%d", &n, &q) != EOF){ for(int i = 1; i <= n; i ++){ scanf("%lld", &a[i]); b[i] = a[i]; } sort(b + 1, b + n + 1); int k = unique(b + 1, b + n + 1) - b - 1; cnt = -1; rt[0] = build(1, k); for(int i = 1; i <= n; i ++){ int x = lower_bound(b + 1, b + k + 1, a[i]) - b; rt[i] = insert(rt[i - 1], x); } for(int i = 1; i <= q; i ++){ int l, r; l = read(), r = read(); if(r - l + 1 < 3){ printf("-1\n"); continue; } int x = query(rt[l - 1], rt[r], r - l + 1); int y = query(rt[l - 1], rt[r], r - l); ll ans = -1; for(int i = r - l - 1; i >= 1; i --){ int z = query(rt[l - 1], rt[r], i); if(b[y] + b[z] > b[x]){ ans = b[x] + b[y] + b[z]; break; } x = y; y = z; } printf("%lld\n", ans); } } return 0; }