zoukankan      html  css  js  c++  java
  • 杭电多校HDU 6601 Keen On Everything But Triangle(主席树)题解

    题意:

    (n)根长度不一的棍子,q次询问,求([L,R])区间的棍子所能组成的周长最长的三角形。棍长(in [1, 1e9]),n(in [1, 1e5])

    思路:

    由于不构成三角形的数组为菲波那切数列,所以当棍数超过44时,长度超过1e9,所以从最大开始数最多不超过45次就能找到构成三角形。所以直接主席树查询区间第k大。复杂度(O(45 * q * logn))

    代码:

    #include<map>
    #include<set>
    #include<cmath>
    #include<cstdio>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<queue>
    #include<cstring>
    #include<string>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn = 1e5 + 5;
    const int INF = 0x3f3f3f3f;
    const ll MOD = 1e9 + 7;
    using namespace std;
    int n, q, tot;
    int root[maxn];
    ll a[maxn];
    vector<ll> vv;
    int getId(ll x){
        return lower_bound(vv.begin(), vv.end(),x) - vv.begin() + 1;
    }
    struct node{
        int lson, rson;
        int sum;
    }T[maxn * 40];
    void update(int l, int r, int &now, int pre, int v, int pos){
        T[++tot] = T[pre], T[tot].sum += v, now = tot;
        if(l == r) return;
        int m = (l + r) >> 1;
        if(m >= pos)
            update(l, m, T[now].lson, T[pre].lson, v, pos);
        else
            update(m + 1, r, T[now].rson, T[pre].rson, v, pos);
    }
    int query(int l, int r, int pre, int now, int k){
        if(l == r) return l;
        int m = (l + r) >> 1;
        int sum = T[T[now].lson].sum - T[T[pre].lson].sum;
        if(sum >= k)
            return query(l, m, T[pre].lson, T[now].lson, k);
        else
            return query(m + 1, r, T[pre].rson, T[now].rson, k - sum);
    }
    void init(){
        memset(T, 0, sizeof(T));
        tot = 0;
        vv.clear();
    }
    int main(){
        while(~scanf("%d%d", &n, &q)){
            init();
            for(int i = 1; i <= n; i++){
                scanf("%lld", &a[i]), vv.push_back(a[i]);
            }
            sort(vv.begin(), vv.end());
            vv.erase(unique(vv.begin(), vv.end()), vv.end());
    
            for(int i = 1; i <= n; i++){
                update(1, vv.size(), root[i], root[i - 1], 1, getId(a[i]));
            }
            while(q--){
                int l, r;
                scanf("%d%d", &l, &r);
                int num = 0;
                ll ans = -1;
                ll a1, a2, a3;
                for(int i = r - l + 1; i >= 1; i--){
                    if(num == 0){
                        a3 = query(1, vv.size(), root[l - 1], root[r], i);
                        num++;
                    }
                    else if(num == 1){
                        a2 = query(1, vv.size(), root[l - 1], root[r], i);
                        num++;
                    }
                    else if(num == 2){
                        a1 = query(1, vv.size(), root[l - 1], root[r], i);
                        num++;
                    }
                    else{
                        a3 = a2, a2 = a1;
                        a1 = query(1, vv.size(), root[l - 1], root[r], i);
                    }
                    if(num == 3 && vv[a1 - 1] + vv[a2 - 1] > vv[a3 - 1]){
                        ans = vv[a1 - 1] + vv[a2 - 1] + vv[a3 - 1];
                        break;
                    }
                }
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    shell进行mysql统计
    java I/O总结
    Hbase源码分析:Hbase UI中Requests Per Second的具体含义
    ASP.NET Session State Overview
    What is an ISAPI Extension?
    innerxml and outerxml
    postman
    FileZilla文件下载的目录
    how to use webpart container in kentico
    Consider using EXISTS instead of IN
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11249003.html
Copyright © 2011-2022 走看看