The maximum perimeter of the triangle section hdu6601

Topic Portal // res tp hdu

purpose

Interval of length n, q given subinterval, whose elements can be constructed maximum perimeter of the triangle. Multiple sets of tests.

n 1e5
q 1e5
ai [1,1e9] (i∈[1,n]);

data structure

Tree divided

analysis

Complete a query in no more than O (logn) time

If a number of columns can not form a triangle, it is a Fibonacci number column. Fiji column is not more than 50 can be achieved by 1e9, so the query each time just before the interval k large can not ask more than 50 times, you can get the number of columns if you can form a triangle

A single partition tree asked the k little / much logn

#include<iostream>
#include<algorithm>
#include<cmath>
typedef long long ll;
using namespace std;
const int MAXN = 100000+50;
const int DEEP = 20;
ll tree[DEEP][MAXN];
int cnt[DEEP][MAXN];
ll sorted[MAXN];
void build(int deep,int lft,int rht)
{
    if(lft == rht) return;
    int mid = (lft + rht)>>1;
    int scnt = mid - lft + 1;
    ll M = sorted[mid];
    for(int i = lft;i<=rht;++i){
        if(tree[deep][i] < M) scnt--;
    }
    int p = lft, r = mid + 1;
    for(int i = lft,cnt_in_left = 0;i<=rht;++i){
        ll num = tree[deep][i];
        if(num < M || (num == M && scnt)){
            if(num == M) scnt--;
            cnt_in_left++;
            tree[deep + 1][p++] = num;
        }
        else tree[deep + 1][r++] = num;
        cnt[deep][i] = cnt_in_left;
    }
    build(deep + 1,lft,mid);
    build(deep + 1,mid + 1,rht);
}
ll query(int deep, int lft, int rht, int qlft, int qrht, int k){
    if(lft == rht) return tree[deep][lft];
    int mid = (lft + rht)>>1;
    int left = 0,sum_in_left = cnt[deep][qrht];
    if(qlft != lft){
        left = cnt[deep][qlft-1];
        sum_in_left-=left;
    }
    if(sum_in_left >= k){
        int new_qlft = lft + left;
        int new_qrht = new_qlft + sum_in_left - 1;
        return query(deep + 1,lft,mid,new_qlft,new_qrht,k);
    }
    else{
        int a = qlft - lft - left;
        int b = qrht - qlft - sum_in_left;
        int new_qlft = (mid + 1) + a;
        int new_qrht = new_qlft + b;
        return query(deep+1,mid+1,rht,new_qlft,new_qrht,k - sum_in_left);
    }
}
int main()
{
    int n,q,l,r;
    while(scanf(" %d %d",&n,&q)!=EOF){
        for(int i = 1;i<=n;++i) {
            scanf(" %lld",&sorted[i]);
            tree[0][i] = sorted[i];
        }
        sort(sorted+1,sorted+1+n);
        build(0,1,n);
        while(q--){
            scanf(" %d %d",&l,&r);
            if(r - l + 1 < 3) printf("-1\n");
            else{
                int len = r - l + 1;
                long long a,b,c,ans = -1;
                a = query(0,1,n,l,r,len);
                b = query(0,1,n,l,r,len-1);
                for(int i = len-2;i>=1;--i){
                    c = query(0,1,n,l,r,i);
                    if(b + c > a){
                        ans = a + b + c;break;
                    }
                    a= b;b = c;
                }
                printf("%lld\n",ans);
            }
        }
    }
}

Guess you like

Origin www.cnblogs.com/tea-egg/p/11242591.html
Recommended