HDU 6070 Dirt Ratio
来源:互联网 发布:璟璞网络福利员 编辑:程序博客网 时间:2024/05/22 01:49
2017多校4-4 Dirt Ratio
线段树,二分法
题意
给你一个数列,求一个子区间,使得:区间内不同数字种类/区间内所有数字个数最小。输出最小值。
思路
二分答案
mid ,检验是否存在一个区间满足size(l,r)r−l+1≤mid ,也就是size(l,r)+mid×l≤mid×(r+1) 。
从左往右枚举每个位置作为r ,当r 变化为r+1 时,对size 的影响是一段区间加1 ,线段树维护区间最小值即可。
时间复杂度O(nlognlogw) 。
每次二分,都重建线段树,叶子初始化为mid*l。线段树每个叶子tree[i]维护是:i到当前枚举位置 这个区间内有多少个不同的数字。
所以二分后针对每个右端点i,与其值a[i],区间更新a[i]上一次出现位置la[a[i]]到i,区间加1,代表这些区间新出现了a[i]这个值。
然后线段树维护区间最小值,每次查询就得出了所有左端点小于当前枚举的位置、构成的所有合法区间,出现不同数字最少的区间。
代码
#include<bits\stdc++.h>#define M(a,b) memset(a,b,sizeof(a))#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int MAXN=500005;struct STree{ double val;int lazy;}stree[MAXN];int a[MAXN], la[MAXN];void pushup(int rt){ stree[rt].val=min(stree[rt<<1].val, stree[rt<<1|1].val);}void pushdown(int rt){ if(stree[rt].lazy) { stree[rt<<1].val+=stree[rt].lazy; stree[rt<<1|1].val+=stree[rt].lazy; stree[rt<<1].lazy+=stree[rt].lazy; stree[rt<<1|1].lazy+=stree[rt].lazy; stree[rt].lazy=0; }}void build(int l, int r, int rt, double k){ stree[rt].lazy=0; if(l==r) { stree[rt].val=k*l; return; } int m=(l+r)>>1; build(lson, k); build(rson, k); pushup(rt);}void update(int L, int R, int l, int r, int rt){ if(L<=l&&r<=R) { stree[rt].val++; stree[rt].lazy++; return; } pushdown(rt); int m=(l+r)>>1; if(L<=m) update(L, R, lson); if(m<R) update(L, R, rson); pushup(rt);}double query(int L, int R, int l, int r, int rt){ if(L<=l&&r<=R) return stree[rt].val; pushdown(rt); int m=(l+r)>>1; double res=1e10; if(L<=m) res=min(res, query(L, R, lson)); if(m<R) res=min(res, query(L, R, rson)); return res;}int main(){ int T;scanf("%d", &T); while(T--) { int n;scanf("%d", &n); for(int i=1;i<=n;i++) scanf("%d", &a[i]); double l=0.0, r=1.0;int tim=20; while(tim--) { double mid=(l+r)/2.0; build(1, n, 1, mid); M(la, 0); bool fl=0; for(int i=1;i<=n&&!fl;i++) { update(la[a[i]]+1, i, 1, n, 1); la[a[i]]=i; if(query(1, i, 1, n, 1)<=mid*(i+1)) fl=1; } if(fl) r=mid; else l=mid; } printf("%.10lf\n", l); }}
阅读全文
0 0
- hdu 6070 Dirt Ratio
- HDU 6070 Dirt Ratio
- HDU-6070 Dirt Ratio
- HDU 6070 Dirt Ratio
- HDU 6070 Dirt Ratio
- hdu 6070 Dirt Ratio
- HDU 6070 Dirt Ratio
- hdu 6070 Dirt Ratio
- HDU 6070 Dirt Ratio
- HDU 6070 Dirt Ratio 线段树 二分
- HDU 6070 Dirt Ratio [二分+线段树]
- hdu 6070 Dirt Ratio 二分,线段树
- hdu 6070 Dirt Ratio(线段树+二分)
- hdu 6070 Dirt Ratio二分 线段树
- HDU 6070 Dirt Ratio 线段树 + 二分
- 【HDU 6070 Dirt Ratio】 二分 & 线段树
- HDU 6070 Dirt Ratio 二分+线段树
- HDU 6070 Dirt Ratio 线段树
- iPhone建立热点-通过USB连接
- 跨域问题:解决跨域的三种方案
- mysql当插入重复数据的时候
- mysql5.5以后的版本安装使用cmake
- 博客初体验
- HDU 6070 Dirt Ratio
- const char*, char const*, char*const的区别
- JSON格式
- hdu6070 线段树+二分
- Steppingstone
- windows下安装scrapy
- Android OpenGL触摸反馈
- 27 款 iOS 开源库,让你的开发溜到飞起
- PHP 基础语法