2019 Multi-University Training Contest 2 - Keen On Everything But Triangle

Chairman of the tree

Chairman of the interval by the number of k-large to maintain, and then can not form a triangle of minimum conditions is pulled Fibonacci series.

Subject only to the scope of 1e9, at worst, only 44 Fibonacci columns, that is to say from our large first, second largest, third largest turn down the judgment, also traverse up to 44 times, can certainly solving within the specified time.

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
#define FAST_IO ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
    int ret = 0, w = 0; char ch = 0;
    while(!isdigit(ch)){
        w |= ch == '-', ch = getchar();
    }
    while(isdigit(ch)){
        ret = (ret << 3) + (ret << 1) + (ch ^ 48);
        ch = getchar();
    }
    return w ? -ret : ret;
}
inline int lcm(int a, int b){ return a / __gcd(a, b) * b; }
template <typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
    A ans = 1;
    for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
    return ans;
}

const int N = 200005;
int n, m, tot, k, a[N], b[N], tree[N*20], lc[N*20], rc[N*20], root[N];

void init(){
    full(a, 0), full(b, 0);
    full(tree, 0), full(root, 0);
    full(lc, 0), full(rc, 0);
    k = tot = 0;
}

int buildTree(int l, int r){
    int cur = ++tot;
    if(l == r) return cur;
    int mid = (l + r) >> 1;
    lc[cur] = buildTree(l, mid);
    rc[cur] = buildTree(mid + 1, r);
    return cur;
}

int insert(int rt, int l, int r, int p){
    int cur = ++tot;
    tree[cur] = tree[rt] + 1, lc[cur] = lc[rt], rc[cur] = rc[rt];
    if(l == r) return cur;
    int mid = (l + r) >> 1;
    if(p <= mid) lc[cur] = insert(lc[rt], l, mid, p);
    else rc[cur] = insert(rc[rt], mid + 1, r, p);
    return cur;
}

int query(int a, int b, int l, int r, int k){
    int p = tree[lc[b]] - tree[lc[a]];
    if(l == r) return l;
    int mid = (l + r) >> 1;
    if(k <= p) return query(lc[a], lc[b], l, mid, k);
    else return query(rc[a], rc[b], mid + 1, r, k - p);
}

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 + n + 1);
        k = unique(b + 1, b + n + 1) - b - 1;
        root[0] = buildTree(1, k);
        for(int i = 1; i <= n; i ++){
            int p = lower_bound(b + 1, b + k + 1, a[i]) - b;
            root[i] = insert(root[i - 1], 1, k, p);
        }
        int l = 0, r = 0;
        while(m --){
            scanf("%d%d", &l, &r);
            int cnt = r - l + 1;
            if(cnt < 3){
                printf("-1\n");
                continue;
            }
            bool good = false;
            int fst = b[query(root[l - 1], root[r], 1, k, cnt)];
            int sed = b[query(root[l - 1], root[r], 1, k, cnt - 1)];
            for(int i = cnt - 2; i >= 1; i --){
                int val = b[query(root[l - 1], root[r], 1, k, i)];
                if(1LL * val + sed > fst){
                    printf("%lld\n", 1LL * val + sed + fst);
                    good = true;
                    break;
                }
                fst = sed, sed = val;
            }
            if(!good) printf("-1\n");
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/onionQAQ/p/11241710.html