hdu 6070二分+线段树
来源:互联网 发布:软件架构 编辑:程序博客网 时间:2024/05/17 00:14
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<queue>#include<stack>#include<set>#include<map>#include<cstdlib>#include<cmath>using namespace std;const double inf = 1e9;const int maxn = 60005;const double eps=1e-5;struct SegTreeNode{ double val; double addMark;//延迟标记}segTree[maxn<<2];//定义线段树int pre[maxn],a[maxn],pos[maxn],n;/*功能:构建线段树root:当前线段树的根节点下标arr: 用来构造线段树的数组istart:数组的起始位置iend:数组的结束位置*/void build(int root, double midd, int istart, int iend){ segTree[root].addMark = 0.0;//----设置标延迟记域 if(istart == iend)//叶子节点 segTree[root].val = istart*midd; else { int mid = (istart + iend) / 2; build(root*2, midd, istart, mid);//递归构造左子树 build(root*2+1, midd, mid+1, iend);//递归构造右子树 //根据左右子树根节点的值,更新当前根节点的值 segTree[root].val = min(segTree[root*2].val, segTree[root*2+1].val); }}/*功能:当前节点的标志域向孩子节点传递root: 当前线段树的根节点下标*/void pushDown(int root){ if(segTree[root].addMark > 0) { //设置左右孩子节点的标志域,因为孩子节点可能被多次延迟标记又没有向下传递 //所以是 “+=” segTree[root*2].addMark += segTree[root].addMark; segTree[root*2+1].addMark += segTree[root].addMark; //根据标志域设置孩子节点的值。因为我们是求区间最小值,因此当区间内每个元 //素加上一个值时,区间的最小值也加上这个值 segTree[root*2].val += segTree[root].addMark; segTree[root*2+1].val += segTree[root].addMark; //传递后,当前节点标记域清空 segTree[root].addMark = 0.0; }}/*功能:线段树的区间查询root:当前线段树的根节点下标[nstart, nend]: 当前节点所表示的区间[qstart, qend]: 此次查询的区间*/double query(int root, int nstart, int nend, int qstart, int qend){ //查询区间和当前节点区间没有交集 if(qstart > nend || qend < nstart) return inf; //当前节点区间包含在查询区间内 if(qstart <= nstart && qend >= nend) return segTree[root].val; //分别从左右子树查询,返回两者查询结果的较小值 pushDown(root); //----延迟标志域向下传递 int mid = (nstart + nend) / 2; return min(query(root*2, nstart, mid, qstart, qend), query(root*2+1, mid + 1, nend, qstart, qend));}/*功能:更新线段树中某个区间内叶子节点的值root:当前线段树的根节点下标[nstart, nend]: 当前节点所表示的区间[ustart, uend]: 待更新的区间addVal: 更新的值(原来的值加上addVal)*/void update(int root, int nstart, int nend, int ustart, int uend, int addVal){ //更新区间和当前节点区间没有交集 if(ustart > nend || uend < nstart) return ; //当前节点区间包含在更新区间内 if(ustart <= nstart && uend >= nend) { segTree[root].addMark += addVal; segTree[root].val += addVal; return ; } pushDown(root); //延迟标记向下传递 //更新左右孩子节点 int mid = (nstart + nend) / 2; update(root*2, nstart, mid, ustart, uend, addVal); update(root*2+1, mid+1, nend, ustart, uend, addVal); //根据左右子树的值回溯更新当前节点的值 segTree[root].val = min(segTree[root*2].val, segTree[root*2+1].val);}bool check(double mid){ build(1,mid,1,n); for(int i=1;i<=n;i++) { update(1,1,n,pos[i]+1,i,1.0); if(query(1,1,n,1,i)<=mid*(i+1.0)) return true; } return false;}int main(){ int t,i; scanf("%d",&t); while(t--&&scanf("%d",&n)!=EOF) { memset(pre,0,sizeof(pre)); for(i=1;i<=n;i++) { scanf("%d",a+i); pos[i]=pre[a[i]]; pre[a[i]]=i; } double mid,l=0,r=1.0; while(r-l>eps) { mid=(r+l)/2; if(check(mid)) r=mid; else l=mid; } printf("%.10f\n",mid); } return 0;}
阅读全文
0 0
- HDU 6070 二分+线段树
- hdu 6070二分+线段树
- HDU 6070 Dirt Ratio 线段树 二分
- HDU 6070 Dirt Ratio [二分+线段树]
- hdu 6070 二分答案+线段树
- hdu 6070 Dirt Ratio 二分,线段树
- hdu 6070 Dirt Ratio(线段树+二分)
- hdu 6070 Dirt Ratio二分 线段树
- HDU 6070 二分查找 + 线段树 + 枚举
- HDU 6070 Dirt Ratio 线段树 + 二分
- 【HDU 6070 Dirt Ratio】 二分 & 线段树
- HDU 6070 Dirt Ratio 二分+线段树
- hdu 6070 二分+线段树维护
- HDU 6070 Dirt Ratio(二分+线段树)
- hdu 4339 线段树+二分
- hdu 4614 线段树+二分~
- HDU 4614 线段树+二分
- HDU 4791二分+线段树
- Python之道(3)---Python生成器
- Mysql安装与配置调优
- ipc$
- PNG文件头格式解析
- 图像面试的一些基本知识
- hdu 6070二分+线段树
- java 基础
- F
- RTP传输H264时的sps和pps的获取
- js之导航栏目弹性运动效果
- stm32f407 输入捕获两路方波,测下降沿时间间隔
- android仿ios版本飞常准app字母列表索引,纯原创。
- 重写toString()和equals()方法(algs4)
- Prim算法