[jzoj 6087] [GDOI2019模拟2019.3.26] 获取名额 解题报告 (泰勒展开+RMQ+精度)-程序员宅基地

技术标签: 数据结构与算法  

题目链接:

https://jzoj.net/senior/#main/show/6087

题目:

题解:
  • 只需要统计$\prod_{i=l}^r (1-\frac{a_i}{x})$
  • =$exp(\sum_{i=l}^r ln(1-\frac{a_i}{x}))(x>a_i)$
  • 我们可以把$ln(1-x)|x<1|$泰勒展开,得到$-\sum_{i=1}^{∞}\frac{x^i}{i}=0-\frac{x}{1}-\frac{x^2}{2}-\frac{x^3}{3}-...$
  • 那么里面化简得到$-\sum_{i=1}^{r} \sum_{j=1}^∞\frac{a_i^j}{x^j*j})=-\sum_{i=1}^∞\frac{1}{i*x^i}\sum_{j=l}^{r}a_j^i$
  • 实测$∞$取$50$就可以,预处理前缀和来快速计算$\sum_{j=l}^{r}a_j^i$
  • 注意把$x=x/max(a_i)$,$a_i=a_i/max(a_i)$,防止爆$double$的范围
  • 但是发现精度会有很大问题
  • 当$\frac{a_i}{x}$较大时,$ln$里面的东西会比较接近$0$,很难保证精度
  • 为$\frac{a_i}{x}$设置一个$lim$,当$\frac{a_i}{x}>lim$时直接算,再递归左右区间
  • $lim$取$0.5​$是可以过的
  • 寻找区间内最大的$\frac{a_i}{x}$用$RMQ$
  • 参考自大米饼大佬的博客
代码:
#include<bits/stdc++.h>
using namespace std;
typedef double db;

const int N=6e5+15;
const int M=50;
int n,q;
int bin[21],lg[N],f[N][21];
db res;
db a[N],s[M+1][N];
inline char gc()
{
  static char*p1,*p2,s[1000000];
  if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
  return(p1==p2)?EOF:*p1++;
}
inline int read()
{
    char ch=gc();int s=0;
    while (ch<'0'||ch>'9') ch=gc();
    while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=gc();}
    return s;
}
int Max(int x,int y) {
    return a[x]>a[y]?x:y;}
void pre()
{
    for (int i=bin[0]=1;i<=20;bin[i]=bin[i-1]<<1,i++);
    lg[0]=-1;
    for (int i=1;i<=n;i++) f[i][0]=i,lg[i]=lg[i>>1]+1;
    for (int i=1;i<=20;i++)
        for (int j=1;j+bin[i]-1<=n;j++)
            f[j][i]=Max(f[j][i-1],f[j+bin[i-1]][i-1]);
}
int ask(int l,int r)
{
    int t=lg[r-l+1];
    return Max(f[l][t],f[r-bin[t]+1][t]);
}
db x;
db cal(int l,int r)
{
    db re=0,t=1;
    for (int i=1;i<=M;i++)
    {
        t*=x;
        re-=(s[i][r]-s[i][l-1])/(i*t);
    }
    return exp(re);
}
void solve(int l,int r)
{
    int mid=ask(l,r);
    if (a[mid]/x<0.5) {res*=cal(l,r);return;}
    res*=1-a[mid]/x;
    if (l<mid) solve(l,mid-1);
    if (r>mid) solve(mid+1,r);
}
int main()
{
    freopen("orz.in","r",stdin);
    freopen("orz.out","w",stdout);
    n=read();q=read();
    db mx=0;
    for (int i=1;i<=n;i++) a[i]=read(),mx=max(mx,a[i]);
    for (int i=1;i<=n;i++) a[i]/=mx;
    pre();
    for (int i=1;i<=n;i++)
    {
        db t=1;
        for (int j=1;j<=M;j++)
        {
            t*=a[i];
            s[j][i]=s[j][i-1]+t;
        }
    }
    while (q--)
    {
        int l=read(),r=read();
        x=read()/mx;
        res=1;solve(l,r);
        printf("%.10f\n",1-res);
    }
    return 0;
}

转载于:https://www.cnblogs.com/xxzh/p/10603977.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30564785/article/details/96691013

智能推荐

CSS背景特殊属性值-程序员宅基地

文章浏览阅读52次。CSS代码示例-背景附着属性(background-attachment)-[背景图固定不动,不跟随滚动条滚动]:<html><head><title>背景附着属性 background-attachment</title><style type="text/css">body {background-image:url(../image..._背景附着方式的属性值

Python-第一阶段-第二章 字面量-程序员宅基地

文章浏览阅读863次,点赞24次,收藏18次。Python字面量

《算法导论》第2章 算法基础(插入排序、归并排序、复杂度计算)_61,55,97,30,38,58两轮选择递增排序法-程序员宅基地

文章浏览阅读1k次。(最近在自己学习《算法导论》一本书,之前本来喜欢手写笔记,但是随即发现自己总是把笔记弄丢,所以打算做一个电子版的笔记)(另外书中用的都是伪代码,笔记中如果需要尝试的地方都是python代码)2.1 插入排序 基本思想:将待排序的数列看成两个部分(以从小到大为例),前一半是排序完成的,后一半是乱序的,对于乱序的第一个,开始和前一半里最大的数字、第二大的数字……依次比较,等到合适的位置就将它放进去。然后比对过的数字向后移动一位,相应的排序完成的长度加一,没有排序的减一。如:5 |..._61,55,97,30,38,58两轮选择递增排序法

把这份关于Android Binder原理一系列笔记研究完,进大厂是个“加分项”(2)-程序员宅基地

文章浏览阅读674次,点赞21次,收藏21次。可以看出,笔者的工作学习模式便是由以下。

Vue实战(三):实现树形表格_vue树形表格组件-程序员宅基地

文章浏览阅读1.1k次。实现树形表格_vue树形表格组件

Linux平台下很实用的44个Linux命令-程序员宅基地

文章浏览阅读237次。Linux平台下很实用的44个Linux命令大家好,今天再继续和大家说下基础的命令,实在是不知道基础的东西还有什么是应该和大家讲的了,要是再开基础的东西,我觉得就得和大家说交换机和路由器什么的了。今天和大家说一下linux运维其实一般来说,能精通100+的命令,就是一个合格的运维人员了,意思就是你的基础已经差不多了。但是在实际运维工作中需要经常运用到的一些命令,今天就和大家简单的说一下,因

随便推点

2023年Java华为OD真题机考题库大全-带答案(持续更新)_华为od机试题-程序员宅基地

文章浏览阅读1.2w次,点赞16次,收藏149次。2023年华为OD真题目前华为社招大多数是OD招聘,17级以下都为OD模式,OD模式也是华为提出的一种新的用工形式,定级是13-17级,属于华为储备人才,每年都会从OD项目挑优秀员工转为正编。D1-D5对应薪资10K-35K左右,年终奖2-4个月,周六加班双倍工资,下个月发。入职OD会有一定薪资上涨,之后每年一次加薪,OD转华为一次加薪。等不到转正机会,相对于内部员工来说,容易被裁,不稳定,可能接触不到核心项目,功能。具体转条件:连续N个季度绩效为A,部门有转正名额,排队。_华为od机试题

python selenium自动化之chrome与chromedriver版本兼容问题_chrome版本122.0.6261.112和chromdriver 107.0.5304.62兼容-程序员宅基地

文章浏览阅读2.7k次,点赞3次,收藏10次。在我们使用python+selenium来驱动chrome浏览器时,需要有chromedriver的支持,但是chrome浏览器更新比较频繁,而chrome浏览器和chromedriver则需要保持版本一致(版本一般相差1以内),此时我们就需要手动下载chromedriver来匹配此时的浏览器,但是生产环境操作比较麻烦。此时,我们就想是不是有一个程序来代替我们完成这个工作呢?思路比较当前的chrome浏览器版本号与chromedriver浏览号如果不匹配,则下载一个新的chromedriver替换掉_chrome版本122.0.6261.112和chromdriver 107.0.5304.62兼容吗

测试人员如何规划自己的职业生涯,分享我这些年的测开的总结给大家参考~_测开个人成长计划-程序员宅基地

文章浏览阅读2.7k次,点赞2次,收藏11次。负责开发项目的技术方法。我的一位同事曾经很认真地问过我一个问题,他说他现在从事软件测试工作已经4年了,但是他不知道现在的工作和自己在工作3年时有什么不同,他想旁观者清,也许我能回答他的问题。随着互联网的飞快发展,IT行业出现了日新月异的变化,新的技术会不断出现,你熟练掌握的软件测试技术很快就过时了。至于第三点说的实践和思考就是你对自己学到的东西的一个掌握的程度的检验了,只有实践了你才能知道,这个知识点你到底学会了没有,会了之后有没有什么其他的理解,这个就是需要自己去思考了 ,这种东西都是别人教不了你的!_测开个人成长计划

MATLAB代码:多微网电能互补与需求响应的微网双层优化模型——动态定价与能量管理_配电网和微电网的matlab模型-程序员宅基地

文章浏览阅读734次,点赞21次,收藏13次。主要内容:代码主要做的是考虑多微网电能互补共享的微网双层优化模型,同时优化配电网运营商的动态电价以及微网用户的能量管理策略,在上层,目标函数为配电网运营商的收益最大化,决策变量为配电网运营商的交易电价;主要内容:代码主要做的是考虑多微网电能互补共享的微网双层优化模型,同时优化配电网运营商的动态电价以及微网用户的能量管理策略,在上层,目标函数为配电网运营商的收益最大化,决策变量为配电网运营商的交易电价;最后,我们输出最终的结果,包括最优的用电费用、配网运营商的收益以及每个微网的用电费用分配情况。_配电网和微电网的matlab模型

基于双极性SPWM调制的三相电压型桥式逆变电路原理解析-程序员宅基地

文章浏览阅读378次,点赞3次,收藏3次。首先介绍了逆变电路的基本原理和应用领域,然后详细分析了双极性SPWM调制方式的工作原理和优势。本文通过对三相电压型桥式逆变电路和双极性SPWM调制方式的技术分析,深入探讨了其在电力系统中的应用和性能评估。双极性SPWM调制方式是SPWM调制方式的一种改进形式,它能够更好地抑制谐波,提高逆变电路的输出质量。面对电力系统的不断发展和需求的变化,逆变电路和SPWM调制方式也在不断演进。为了评估三相电压型桥式逆变电路和双极性SPWM调制方式的性能,本节将详细分析其输出波形的失真程度、功率损耗和效率等关键指标。

用cmake 编译 xcode用的clucene静态库(一)_clucene-config.h-程序员宅基地

文章浏览阅读4.5k次。第一步、下载源代码 http://sourceforge.net/projects/clucene/ 第二步、下载cmakehttp://www.cmake.org/cmake/resources/software.html 编译第一步,打开在应用程序中的cmake GUI程序,设置好源代码路径,和输出路径,如图: 第二步,点击Configure,在_clucene-config.h

推荐文章

热门文章

相关标签