2019 Multi-University Training Contest 2 —— Keen On Everything But Triangle(组成三角形 斐波那契数列性质 主席树)

原题: http://acm.hdu.edu.cn/showproblem.php?pid=6601

题意:

给出n数组,每次询问,求出区间内的数可组成的周长最大的三角形。

解析:

显然在对区间排序后,答案的三个数一定连续。

考虑三个连续的数不能组成三角形的情况:有 a + b < = c a+b<=c a+b<=c

那么极限的情况应该是:
1 , 1 , 2 , 3 , 5 , 8 , 13... 1,1,2,3,5,8,13... 1,1,2,3,5,8,13...,到了40多项就大于1e9了,所以说,只需要求出区间的最大的50个数即可得到答案。

这个东西用主席树做一下就行。

代码:

#include
using namespace std;
#define N 100005
#define LL long long
int root[N];
int siz[N*40],lchild[N*40],rchild[N*40];
int tot;
void insert(int last,int cur,int L,int R,int k) { //单点更新
    siz[cur]=siz[last]+1;//将前一个树的信息复制过来
    lchild[cur]=lchild[last];
    rchild[cur]=rchild[last];
    if(L==R)
        return ;
    int mid=L+R>>1;
    if(k<=mid)
        insert(lchild[last],lchild[cur]=++tot,L,mid,k);//对于需要更改的节点都需要新增节点
    else
        insert(rchild[last],rchild[cur]=++tot,mid+1,R,k);
}
int query(int last,int cur,int k,int L,int R) {
    if(L==R)
        return L;
    int mid=L+R>>1;
    int lsum=siz[lchild[cur]]-siz[lchild[last]];
    if(lsum>=k)
        return query(lchild[last],lchild[cur],k,L,mid);
    else
        return query(rchild[last],rchild[cur],k-lsum,mid+1,R);
}
int a[N],b[N],n,m,l,r,k;
int main() {
    while(scanf("%d%d",&n,&m)!=EOF) {
        memset(siz,0,sizeof siz);
        memset(lchild,0,sizeof lchild);
        memset(rchild,0,sizeof rchild);
        tot=0;
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        int t=unique(b+1,b+n+1)-b-1;
        for(int i=1; i<=n; i++)
            insert(root[i-1],root[i]=++tot,1,t,lower_bound(b+1,b+t+1,a[i])-b);
        for(int i=0; i<m; i++) {
            vector<int>v(52);
            scanf("%d%d",&l,&r);
            for(int j=1; j<=min(50,r-l+1); j++) {
                v[j]=(b[query(root[l-1],root[r],r-l+2-j,1,t)]);
            }
            LL ans=-1;
            for(int i=1; i+2<=min(50,r-l+1); i++) {
                if(v[i+1]+v[i+2]>v[i]) {
                    ans=(LL)v[i+1]+(LL)v[i+2]+(LL)v[i];
                    break;
                }
            }
            printf("%lld\n",ans);
        }
    }

}


你可能感兴趣的:(想法题,数据结构)