2019.02.14 codechef Chef at the Food Fair(线段树+泰勒展开)
传送门
题意:现在有nnn个位置,每个位置上有一个值aia_iai.
要求支持如下两种操作:
- 区间乘vvv
- 求区间的(1−ai)(1-a_i)(1−ai)之积
思路:
考虑转换式子:
Ans=∏i=lr(1−ai)=e∑i=lrln(1−ai)Ans=\prod_{i=l}^r(1-a_i)=e^{\sum_{i=l}^rln(1-a_i)}Ans=∏i=lr(1−ai)=e∑i=lrln(1−ai)
于是只需维护∑i=lrln(1−ai)\sum_{i=l}^rln(1-a_i)∑i=lrln(1−ai)
把这个式子在x0=0x_0=0x0=0出泰勒展开可以得到:ln(1−x)=−x−12x2−13x3−⋯˙ln(1-x)=-x-\frac 12x^2-\frac 13x^3-\dot\cdotsln(1−x)=−x−21x2−31x3−⋯˙
因为允许一定的精度误差。
于是我们维护这个多项式的前若干项即可。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
const int N=1e5+5;
double a[N];
int n,m;
namespace SGT{
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
struct Val{
double a[100];
inline double&operator[](const int&k){return a[k];}
inline const double&operator[](const int&k)const{return a[k];}
};
struct Tag{double a;};
const Tag tag_empty=(Tag){1};
Val val_empty;
inline Val operator+(const Val&a,const Val&b){
Val ret;
for(ri i=0;i<100;++i)ret[i]=a[i]+b[i];
return ret;
}
inline void operator+=(Val&a,const Val&b){a=a+b;}
inline Tag operator+(const Tag&a,const Tag&b){return (Tag){a.a*b.a};}
inline void operator+=(Tag&a,const Tag&b){a=a+b;}
inline Val operator+(const Val&a,const Tag&b){
Val ret;
double mult=b.a;
for(ri i=0;i<100;++i)ret[i]=a[i]*mult,mult*=b.a;
return ret;
}
inline void operator+=(Val&a,const Tag&b){a=a+b;}
inline Val solve1(double a){
Val ret=val_empty;
double mult=a;
for(ri i=0;i<100;++i)ret[i]=-mult/(i+1),mult*=a;
return ret;
}
inline double solve2(Val a){
double ret=0.0;
for(ri i=0;i<100;++i)ret+=a[i];
return ret;
}
struct Node{Val val;Tag tag;int l,r;}T[N<<2];
inline void pushup(int p){T[p].val=T[lc].val+T[rc].val;}
inline void pushnow(int p,Tag v){T[p].val+=v,T[p].tag+=v;}
inline bool check(Tag a){return fabs(a.a-1)<=1e-9;}
inline void pushdown(int p){
if(check(T[p].tag))return;
pushnow(lc,T[p].tag),pushnow(rc,T[p].tag);
T[p].tag=tag_empty;
}
inline void build(int p,int l,int r){
T[p]=(Node){val_empty,tag_empty,l,r};
if(l==r){T[p].val=solve1(a[l]);return;}
build(lc,l,mid),build(rc,mid+1,r),pushup(p);
}
inline void update(int p,int ql,int qr,Tag v){
if(ql<=T[p].l&&T[p].r<=qr)return pushnow(p,v);
pushdown(p);
if(ql<=mid)update(lc,ql,qr,v);
if(qr>mid)update(rc,ql,qr,v);
pushup(p);
}
inline Val query(int p,int ql,int qr){
if(ql<=T[p].l&&T[p].r<=qr)return T[p].val;
pushdown(p);
Val ret=val_empty;
if(ql<=mid)ret+=query(lc,ql,qr);
if(qr>mid)ret+=query(rc,ql,qr);
return ret;
}
#undef lc
#undef rc
#undef mid
}
int main(){
for(ri i=0;i<100;++i)SGT::val_empty[i]=0;
n=read(),m=read();
for(ri i=1;i<=n;++i)scanf("%lf",&a[i]);
SGT::build(1,1,n);
double x;
for(ri l,r,op;m;--m){
op=read(),l=read(),r=read();
if(!op)printf("%.8lf\n",exp(SGT::solve2(SGT::query(1,l,r))));
else scanf("%lf",&x),SGT::update(1,l,r,(SGT::Tag){x});
}
return 0;
}
2019.02.14 codechef Chef at the Food Fair(线段树+泰勒展开)的更多相关文章
- 2019.02.28 bzoj4199: [Noi2015]品酒大会(sam+线段树)
传送门 题意:给一个串,每个位置有一个权值,当S[s...s+len−1]=S[t...t+len−1]&&S[s...s+len]̸=S[t..t+len]S[s...s+len-1 ...
- 2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集)
2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集) https://www.luogu.com.cn/problem/CF811E Ste ...
- 2019.02.15 codechef Favourite Numbers(二分+数位dp+ac自动机)
传送门 题意: 给444个整数L,R,K,nL,R,K,nL,R,K,n,和nnn个数字串,L,R,K,数字串大小≤1e18,n≤65L,R,K,数字串大小\le1e18,n\le65L,R,K,数字 ...
- 【线段树 泰勒展开】Codechef April Challenge 2018 Chef at the Food Fair
第一次写泰勒展开:本地和CC差距好大 题目大意 大厨住的城市里办了一场美食节.一条街上开设了$N$个摊位,编号为$1∼N$.这天开始时,第$i$个摊位的食物会导致食物中毒的概率是$P_i$.在这一天中 ...
- CodeChef DISTNUM2 Easy Queries 节点数组线段树
Description You are given an array A consisting of N positive integers. You have to answer Q queries ...
- UVAlive7141 BombX 14年上海区域赛D题 线段树+离散化
题意:一个无限大的棋盘, 有n个小兵, 给出了n个兵的坐标, 现在有一个长为width 高为height的炸弹放在棋盘上, 炸弹只能上下左右平移, 不能旋转. 且放炸弹的区域不能含有士兵, 炸弹可以一 ...
- 2019.01.22 bzoj3333: 排队计划(逆序对+线段树)
传送门 题意简述:给出一个序列,支持把ppp~nnn中所有小于等于apa_pap的'扯出来排序之后再放回去,要求动态维护全局逆序对. 思路:我们令fif_ifi表示第iii个位置之后比它大的数的个 ...
- 2019.01.13 loj#6515. 贪玩蓝月(线段树分治+01背包)
传送门 题意简述:有一个初始为空的双端队列,每次可以在队首和队尾插入或弹出一个二元组(wi,vi)(w_i,v_i)(wi,vi),支持询问从当前队列中选取若干个元素是的他们的和对 MODMODM ...
- 2019.01.13 bzoj4137: [FJOI2015]火星商店问题(线段树分治+可持久化01trie)
传送门 题意:序列上有nnn个商店,有两种事件会发生: sss商店上进购标价为vvv的一个物品 求编号为[l,r][l,r][l,r]之间的位置买ddd天内新进购的所有物品与一个数xxx异或值的最大值 ...
随机推荐
- ros有一个比较安全的登录方案:二次登录防火墙
原文: https://www.winbox.org/ /ip firewall address-list add address=10.0.0.0/8 list=login /ip firewall ...
- Python安装与Pycharm使用入门
一.安装Python 1.Linux下安装 一般系统默认已安装2.6.6版本,升级成2.7版本, 但 2.6 不能删除,因为系统对它有依赖,epel源里最新的也是2.6版本,所以以源代码的方式安装2. ...
- profile default
SAPDBHOST = 10.199.0.26 j2ee/dbtype = hdb j2ee/dbname = ISD j2ee/dbhost = 10.199.0.26 dbs/hdb/dbname ...
- 关于mysql的删除和安装
mysql删除不干净大概有两点1.文件残留 2.注册表 删除:https://www.cnblogs.com/solargen/p/6838657.html 安装:https://www.cnblog ...
- ARCore中Pose类变换点的算法实现
ARCore中Pose类变换点的算法实现,主要分为两步,分别是平移和旋转. 1. 旋转向量:通过四元数计算旋转后的向量 参数列表:q表示四元数, v是长度为4的float数组,表示待旋转的向量, ...
- LVM逻辑卷疑问?
创建完逻辑卷后,删除以/dev/vdb1和/dev/vdb2为基础的分区后,逻辑卷依然生效???
- intllij IDE 中git ignore 无法删除target目录下的文件
原因: git的本地忽略设置必须保证git的远程仓库分支上没有这个要忽略的文件,如果远程分支上存在这个文件,本地在设置ignore 这个文件,将会失败,无法commit忽略.(有人说是git的bug, ...
- 阿里云ODPS <====>蚂蚁大数据
1.命令行客户端工具的安装参考文档:http://repo.aliyun.com/odpscmd/?spm=a2c4g.11186623.2.17.5c185c23zHshCq 2.创建和查看表:ht ...
- 如何创建.gitignore文件,忽略不必要提交的文件
1.gitignore 在工程实现过程中,会生成一些中间文件,或者在项目中的部分文件是不需要进行版本管理的.对于这些文件应该对于Github来讲是透明的.Github提供这种功能,可以自己指定哪些文件 ...
- css选择器querySelector
* querySelector(css选择器)* 通过css选择器去获取一个元素* 它获取到的只有一个元素,如果说是有重复的,那它只取第一个** 主语* document 从整个文档里去获取元素* 父 ...