hdu6070 多校第四场 线段树+二分
来源:互联网 发布:智能电视网络dns设置 编辑:程序博客网 时间:2024/05/21 01:31
看了题解才知道这怎么做,其实之前做过一道类似的线段树的题这里,但是比赛的时候还是没有做出来。
根据官方给的题解 其实我们要求的就是这个
那么我们令
现在就是求一个最小的ans,我们来二分枚举答案,也就是说如果存在:
那么也就是说二分应该缩短右区间,反之亦然。
我们通过简单的变化得到
然后就是用线段树来维护左边的式子,一开始先把l*mid更新到线段树去,然后从左往右枚举r,每次对上一个出现这个数的位置到当前位置的区间值加一表示区间不同的数的个数加一,也就是
#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<string>#include<set>#include<map>#include<queue>#include<stack>#include<cstring>#define clr(x) memset(x,0,sizeof(x))using namespace std;#define LL long longint dat[60005];int last[60005];int cur[60005];struct node{ double cnt; double minnum;}tree[600005<<2];int n;void PushUp(int now){ tree[now].minnum = min(tree[now<<1].minnum,tree[now<<1|1].minnum);}void PushDown(int now){ if(tree[now].cnt!=0) { int lson = now << 1; int rson = now << 1|1; tree[lson].cnt += tree[now].cnt; tree[rson].cnt += tree[now].cnt; tree[lson].minnum += tree[now].cnt; tree[rson].minnum += tree[now].cnt; tree[now].cnt = 0; }}void Update(int ul,int ur,int l,int r,double val,int now){ if(ul<=l && r <= ur) { tree[now].minnum += val; tree[now].cnt += val; return; } PushDown(now); int mid = (l+r)/2; if(ul<=mid) Update(ul,ur,l,mid,val,now<<1); if(ur>mid) Update(ul,ur,mid+1,r,val,now<<1|1); PushUp(now);}double Query(int ql,int qr,int l,int r,int now){ if(ql<=l && r <= qr) { return tree[now].minnum; } PushDown(now); double a1,a2; a1 = a2 = 99999999; int mid = (l+r)/2; if(ql<=mid) { a1 = Query(ql,qr,l,mid,now<<1); } if(qr>mid) { a2 =Query(ql,qr,mid+1,r,now<<1|1); } return min(a1,a2);}bool judge(double p){ clr(tree); for(int i = 1;i<=n;i++) { Update(i,i,1,n,p*i,1); } for(int i = 1;i<=n;i++) { Update(last[i]+1,i,1,n,1,1); double q = Query(0,i,1,n,1); if(q<(i+1)*p) { return true; } } return false;}double GetAns(){ double s = 0; double e = 1; double mid; for(int i = 0;i<20;i++) { mid = (s+e)/2; //cout << s << " " << e << endl; if(judge(mid)) { e = mid; } else s = mid; } return mid;}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%d",&n); clr(last); clr(cur); for(int i = 1;i<=n;i++) { scanf("%d",&dat[i]); last[i] = cur[dat[i]]; cur[dat[i]] = i; } double ans = GetAns(); printf("%.9lf\n",ans); } return 0;}
阅读全文
0 0
- hdu6070 二分+线段树 2017多校第四场1004
- hdu6070 多校第四场 线段树+二分
- (hdu6070)2017杭电多校联赛第四场-Dirt Ratio 线段树+二分
- [hdu6070] 2017hdu多校第四场
- hdu6070 二分+线段树
- HDU6070 二分 线段树
- hdu6070 线段树+二分
- HDU6070(二分+线段树区间更新)
- HDU6070 Dirt Ratio(线段树+二分)
- hdu6070 Dirt Ratio(二分+线段树)
- HDU 6070 Dirt Ratio(二分+线段树 17多校第四场)
- HDU 6070 Dirt Ratio(二分+线段树 17多校第四场)
- HDU6070(线段树)
- HDU 6070-Dirt Ratio(多校训练第四场->二分+线段树)
- 2017多校训练赛第四场 HDU 6070(二分答案+线段树+扫描线)
- HDU6070 2017杭电多校联赛第四场-Dirt Ratio
- hdu6070 Dirt Ratio (线段树:二分+多次建树+构造难想)
- HDU 4638 Group 多校第四场(线段树+离线询问)
- HDU
- 【SQL优化】MySQL优化(概述)
- JS中带返回值的构造函数
- CVPR—2017会议全套视频下载地址分享
- 字符串
- hdu6070 多校第四场 线段树+二分
- 动态规划——POJ3666 Making the Grade
- eclipse导入spring源码
- ServletContext 与application的异同
- JS中常用的对象
- R语言中library()和require()的区别
- delphi 线程应用简单例子
- POJ
- Linux系统ftp服务