首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >2019HDU多校赛第二场 HDU 6601 Keen On Everything But Triangle( 主席树求区间第k大)

2019HDU多校赛第二场 HDU 6601 Keen On Everything But Triangle( 主席树求区间第k大)

作者头像
用户2965768
发布2019-08-01 11:01:32
发布2019-08-01 11:01:32
4850
举报
文章被收录于专栏:wymwym

题意:求区间[ l , r ]能构成三角形周长最大的,不存在就输出-1

解:主席树模版

代码语言:javascript
复制
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 300000;
int sum[maxn*20+5];//sum为森林的不同根结点
struct E {
    ll num;
    int l,r;
} t[maxn*20+5]; //t为tree树
int n,sz,m,cnt;
ll a[maxn],b[maxn];
int build(int l,int r) {
    int now = ++cnt;
    int mid = (l+r)>>1;
    if(l<r) {
        t[now].l = build(l,mid);
        t[now].r = build(mid+1,r);
    }
    return now;
}
int update(int l,int r,int last,int p) {
    int now = ++cnt;
    t[now].num = t[last].num+1;
    t[now].l = t[last].l;
    t[now].r = t[last].r;
    int mid = (l + r)>>1;
    if(l<r) {
        if(p<=mid)t[now].l = update(l,mid,t[last].l,p);
        else t[now].r = update(mid+1,r,t[last].r,p);
    }
    return now;
}
ll query(int u,int v,int l,int r,int k) {
    if(l==r)return l;
    // v 左孩子包含点个数减去 u 左孩子包含点的个数
    int tmp = t[t[v].l].num - t[t[u].l].num;
    int mid = (l+r)>>1;
    if(k<=tmp)return query(t[u].l,t[v].l,l,mid,k);
    else return query(t[u].r,t[v].r,mid+1,r,k - tmp);
}
bool judge(ll x,ll y,ll z){
    if(y+z>x){
        return true;
    }
    return false;
}
int main() {
    ll t1,t2,t3;
    while(scanf("%d %d",&n,&m)==2) {
        for(int i=1; i<=n; i++)scanf("%lld",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        sz = unique(b+1,b+n+1) - (b+1);
        cnt = 0;
        sum[0] = build(1,sz);//建立空树
        for(int i=1; i<=n; i++) a[i] = lower_bound(b+1,b+sz+1,a[i]) - b;
        for(int i=1; i<=n; i++) sum[i] = update(1,sz,sum[i-1],a[i]);
        while(m--) {
            int u,v,k = 4,flag=0;
            scanf("%d %d",&u,&v);
            if(v-u+1<3){
                printf("-1\n");
                continue;
            }
            int len = v - u  + 1;
            t1 = query(sum[u-1],sum[v],1,sz,len-1+1);    t1 = b[t1];
            t2 = query(sum[u-1],sum[v],1,sz,len - 2+1);    t2 = b[t2];
            t3 = query(sum[u-1],sum[v],1,sz,len-3+1);    t3 = b[t3];
            
            while(1){
                if(judge(t1,t2,t3)){
                    flag = 1;
                    break;
                }
                if(k>len)break;
                t1 = t2;    t2 = t3;
                t3 = query(sum[u-1],sum[v],1,sz,len-k+1);    t3 = b[t3];
                k++;    
            }
            if(flag)printf("%lld\n",t1+t2+t3);
            else     printf("-1\n");
        }
    }
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年07月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档