HDU - 6601 Keen On Everything But Triangle 主席树

Keen On Everything But Triangle

Feeling much better and more recently the school sub-sub-Chairman of the tree, but I am very dish, I have not learned the Chairman of the tree, watching his teammates written questions can only draw water, \ (WA \) you still can not help \ (Debug \) , so I decided to learn about the Chairman of the tree after careful consideration.

The meaning of problems

I asked \ ([l, r] \ ) taking three digital interval triangle configuration, can ask the maximum perimeter of the triangle is composed of many, if not form a triangle output? \ ( "- 1" \) .

Thinking

  • Triangle formed by:
    1. Three sides
    2. Is greater than the third side and the two sides of a
  • And then, we are looking for the largest circumference, then we can easily think of taking the maximum three sides, if not to postpone down.

  • We found a lot of inquiries,violenceCertainly not. So in fact we will find, can not form a triangle on either side of that sum is less than equal to the third side, you can think of Fibonacci column is greater than the sum of the first two third side, if you have not qualified, then we You will only find about \ (44 \) sequence \ (k \) large value, certainly not out.
  • Then I want to understand only after we startedviolenceA. In fact, with the Chairman of the tree to maintain the number of columns in the (\ log {n} \) \ find the first time \ (k \) large value, then forced by the Chairman of the tree to find the largest, second largest ... and violence find the longest circumference on \ (ok \) a.

    AC Code

#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pii        pair<int, int>

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 1e5 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

struct Node{
    int l, r, cnt;
}node[maxn*40];
int w[maxn];
int n, m;
int cas, tol, T;
vector<int> vv;
int a[maxn];

void update(int l, int r, int &x, int y, int pos){
    tol++;
    x = tol;
    node[x] = node[y];
    node[x].cnt++;
    if(l == r) return;
    int mid = l+r>>1;
    if(pos <= mid)
        update(l, mid, node[x].l, node[y].l, pos);
    else
        update(mid+1, r, node[x].r, node[y].r, pos);
}

int query(int l, int r, int x, int y, int k){
    if(l == r)
        return l;
    int mid = l+r>>1;
    int cnt = node[node[y].l].cnt - node[node[x].l].cnt;
    if(cnt >= k)
        return query(l, mid, node[x].l, node[y].l, k);
    else
        return query(mid+1, r, node[x].r, node[y].r, k-cnt);
}

int getid(int x){
    return lower_bound(vv.begin(), vv.end(), x) - vv.begin()+1;
}

int main() {
    while(~scanf("%d%d", &n, &m)){
        vv.clear();
        tol = 0;
        mes(w, 0);
        for(int i = 1; i <= n; i++){
            scanf("%d",&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++){
            int pos = getid(a[i]);
            update(1, n, w[i], w[i-1], pos);
        }
        while(m--){
            int l, r;
            scanf("%d%d", &l, &r);
            int b[4], flag = 0;
            if(r - l + 1 < 3){
                printf("-1\n");
                continue;
            }
            b[1] = query(1, n, w[l-1], w[r], r-l+1)-1;
            b[2] = query(1, n, w[l-1], w[r], r-l)-1;
            for(int k = r-l-1; k >= 1; k--){
                b[3] = query(1, n, w[l-1], w[r], k)-1;
                if(vv[b[1]] < vv[b[2]]+vv[b[3]]){
                    printf("%lld\n", 1ll*vv[b[1]]+vv[b[2]]+vv[b[3]]);

                    flag = 1;
                    break;
                }
                for(int i = 1; i <= 2; i++)
                    b[i] = b[i+1];
            }
            if(!flag)
                printf("-1\n");
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/zhuyou/p/11291583.html