hdu6601 Keen On Everything But Triangle 主席树+斐波那契数列妙用

Posted liyishui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu6601 Keen On Everything But Triangle 主席树+斐波那契数列妙用相关的知识,希望对你有一定的参考价值。

题意:

给定序列a,ai为第i根木棍长度,给出q个询问

每次问[L,R]内能构成三角形的最大周长是多少

题解:

属于那种没有往这个方向想就很难想到,然后一直想不到的题2333

因为周长要最大,贪心地优先考虑第一大,第二大,第三大能不能组成合法的三角形

假设不行,那第一根肯定是废了

因为任意两边之和大于第三边->最小的两边之和要大于第三边

第二和第三都搞不定第一,那其他的更不行

接下来继续考虑第二大,第三大,第四大...

但是会担心复杂度怎么办?

怎么办?考虑最坏情况,一直找不到,且构成斐波那契关系

则斐波那契的第45项数已经超过1e9了

说明如果有答案,则在45次内必能找到

如果-1,也能在45次内确定(因此区间长度>=45的话肯定是会有答案的,如果一定没有,则在45次内也能知道,不会tle)

 

#include<bits/stdc++.h>
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
using namespace std;
const int N=2e5+5;
const int maxn=N*40;
int cnt,n,m,q;
int b[N],a[N],tmp[N];
struct pesis_seg
    int ls[maxn],rs[maxn],rt[maxn],sum[maxn];
    void build(int &o,int l,int r)
        o=++cnt;
        if(l==r) 
            return;
        
        int mid=(l+r)>>1;
        build(ls[o],l,mid);
        build(rs[o],mid+1,r);
    
    int update(int o,int l,int r,int pos)
        int oo=++cnt;//相当于动态开点 
        ls[oo]=ls[o];rs[oo]=rs[o];sum[oo]=sum[o]+1;
        if(l==r)
            return oo;
        
        int mid=(l+r)>>1;
        if(pos<=mid) ls[oo]=update(ls[o],l,mid,pos);
        else rs[oo]=update(rs[o],mid+1,r,pos);
        return oo;
    
    int query(int kth,int u,int v,int l,int r)
        if(l==r)
            return l;
        
        int mid=(l+r)>>1;
        int x=sum[ls[v]]-sum[ls[u]];
        //cout<<kth<<" "<<u<<" "<<v<<" "<<l<<" "<<r<<" "<<x<<endl;
        if(x>=kth) return query(kth,ls[u],ls[v],l,mid);
        else return query(kth-x,rs[u],rs[v],mid+1,r);
    
t;
int main()
    //fastio;
    //freopen("lys.in","r",stdin);
    //freopen("lys.in","r",stdin);
    while(scanf("%d %d",&n,&q)!=EOF)
    
    for(int i=1;i<=cnt;i++) t.rt[i]=t.sum[i]=t.ls[i]=t.rs[i]=0;
    cnt=0;
    
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
    sort(b+1,b+n+1);
    int len=unique(b+1,b+n+1)-(b+1);
    t.build(t.rt[0],1,len);
    for(int i=1;i<=n;i++)
        //    int update(int o,int pre,int l,int r,int pos,int val)
        int pos=lower_bound(b+1,b+len+1,a[i])-b;
        t.rt[i]=t.update(t.rt[i-1],1,len,pos);
    
    
    for(int ii=1;ii<=q;ii++)
        int l,r;
        scanf("%d%d",&l,&r);
        int mx=r-l+1;
        bool flag=false;
        int v[5];
        for(int i=1;i<=mx-2;i++)
            v[1]=b[t.query(mx-i+1,t.rt[l-1],t.rt[r],1,len)];
            v[2]=b[t.query(mx-i,t.rt[l-1],t.rt[r],1,len)];
            v[3]=b[t.query(mx-i-1,t.rt[l-1],t.rt[r],1,len)];
            if(v[1]<v[2]+v[3])
                flag=true;
                ll ans=(ll)v[1]+v[2]+v[3];
                printf("%lld\\n",ans);
                break;
            
        
        if(!flag) printf("%d\\n",-1);
    
    
    

 

以上是关于hdu6601 Keen On Everything But Triangle 主席树+斐波那契数列妙用的主要内容,如果未能解决你的问题,请参考以下文章

hdu 6601 (主席树)

ACM的探索之Keen On Evrything But Triangle(我觉得可以很接近啦!!)

2019年7月做题记录

ruby 猴子补丁用keen.io保存查询

Keen.io 仪表板图表上的最大和最小 Y 轴值

ruby 该要点向您展示了如何运行保留分析。我在博客上写了如何在此处运行保留分析:https://keen.io/blog/47823687779