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 主席树+斐波那契数列妙用的主要内容,如果未能解决你的问题,请参考以下文章
ACM的探索之Keen On Evrything But Triangle(我觉得可以很接近啦!!)
ruby 该要点向您展示了如何运行保留分析。我在博客上写了如何在此处运行保留分析:https://keen.io/blog/47823687779