hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
2017-08-04 12:21
561 查看
Dirt Ratio
题目链接:Dirt Ratio题意:x为区间数字的种数,y为区间长度,求x/y的最小值。
官方题解:
size(l,r)r−l+1<=mid转化为size(l,r)+mid∗l<=mid∗(r+1)是关键性的一步。
转化后我们就可以通过线段树来维护size(l,r)+mid∗l的最小值了
线段树保存的是size(l,r)+mid∗l,然后枚举右端点r,判断如果在区间[i,r](1<=i<=r)满足上式,那就可以缩小范围继续枚举答案
代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxn=6e4+10; const double inf=9999999.0; const double eps=1e-5; struct Segtree { double val,lazy; int le,ri; int mid() { return (le+ri)>>1; } } tree[maxn<<2]; int last_apper[maxn],a[maxn]; int n; void Build(int rt,int le,int ri,double num) { tree[rt].lazy=0;//注意lazy不要忘记清0 tree[rt].le=le,tree[rt].ri=ri; if(le==ri) { tree[rt].val=num*le; return ; } int mid=tree[rt].mid(); Build(rt<<1,le,mid,num); Build(rt<<1|1,mid+1,ri,num); tree[rt].val=min(tree[rt<<1].val,tree[rt<<1|1].val); } void Pushdown(int rt) { tree[rt<<1].lazy+=tree[rt].lazy; tree[rt<<1].val+=tree[rt].lazy; tree[rt<<1|1].lazy+=tree[rt].lazy; tree[rt<<1|1].val+=tree[rt].lazy; tree[rt].lazy=0; } void Update(int rt,int le,int ri,int num) { if(le<=tree[rt].le&&tree[rt].ri<=ri) { tree[rt].lazy+=num; tree[rt].val+=num; return ; } if(tree[rt].lazy) Pushdown(rt); int mid=tree[rt].mid(); if(le<=mid) Update(rt<<1,le,ri,num); if(ri>mid) Update(rt<<1|1,le,ri,num); tree[rt].val=min(tree[rt<<1].val,tree[rt<<1|1].val); } double Query(int rt,int le,int ri) { if(le<=tree[rt].le&&tree[rt].ri<=ri) return tree[rt].val; if(tree[rt].lazy) Pushdown(rt); int mid=tree[rt].mid(); double minn=inf; if(le<=mid) minn=Query(rt<<1,le,ri); if(ri>mid) minn=min(minn,Query(rt<<1|1,le,ri)); tree[rt].val=min(tree[rt<<1].val,tree[rt<<1|1].val); return minn; } bool judge(double x) { Build(1,1,n,x); memset(last_apper,0,sizeof(last_apper)); for(int i=1; i<=n; ++i) { Update(1,last_apper[a[i]]+1,i,1); last_apper[a[i]]=i; if(Query(1,1,i)<=x*(i+1)) return true; } return false; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1; i<=n; ++i) scanf("%d",&a[i]); double l=0,r=1,ans=0; while(l<=r) { double mid=(l+r)/2.0; if(judge(mid)) { ans=mid; r=mid-eps; } else l=mid+eps; } printf("%.10lf\n",ans); } return 0; }
相关文章推荐
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- 2017 Multi-University Training Contest - Team 4 HDU 6070 Dirt Ratio (二分+ 线段树)
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- 2017 Multi-University Training Contest - Team 4 :Dirt Ratio(二分+线段树)
- HDU 6070 Dirt Ratio (二分+线段树, 2017 Multi-Univ Training Contest 4)
- HDU 6039 Gear up 2017 Multi-University Training Contest - Team 1 线段树维护到树根距离 区间修改 区间最值
- 2017 Multi-University Training Contest - Team 9 1002&&HDU 6162 Ch’s gift【树链部分+线段树】
- HDU 6070 - Dirt Ratio | 2017 Multi-University Training Contest 4