What's more, a gambler is in nnn casinos. He has PIP in every casino_ The winning rate of IPI, if it wins, it will go to the right, if it loses, it will go to the left. If it reaches casino 000 or n+1n+1n+1, it will be quite a gamble out. Defining the ruling range [l,r][l,r][l,r], that is, in the lll casino, you can't lose, and in a certain gambling, you can win in the casino rrr to end gambling.
Now there are two operations: 1. Modify the winning rate of a casino
2. What is the probability of ruling [l,r][l,r][l,r]
= f [i + 1] * p[i]+f[i − 1] * (1 − p[i])
The difference is 2. We try to reduce it to 1i+1 and i − 1. The difference is 2. We try to reduce it to 1
g[i] * p[i]
4. We separate variable g[i+1]=1 − p[i]p[i] * g[i]4. We separate variable g[i+1]=*g[i]4. We separate variable g[i+1]=p[i]1 − p[i] * g[i]
5. According to the definition f[r+1]=1,f[l − 1] = 0; and g[i]=f[i] − f[i − 1], then Σ i=lr+1g[i]=f[r+1] − f[l − 1] = 15. According to the definition f[r+1]=1,f[l-1]=0; and g[i]=f[i]-f[i-1], then \ sum_^g[i]=f[r+1]-f[l-1]=15. According to the definition f[r+1]=1,f[l − 1] = 0; and g[i]=f[i] − f[i − 1], then Σ i=lr+1 g[i]=f[r+1] − f[l − 1] = 1
1] = g[l]+g[l] * +, Later, g[l]+g[l] * u[l]+g[l] * u[l] * u[l+1]...+g[l] * u[l] * u[r] all become g[l]
[l], f[l − 1] = 0, then f[l]=g[l], so the problem becomes to find g[l]
[l] * u [L + 1] *.... * u[r])=18. Then, we put forward the g[l] in formula 6, g[l] * (1+u[l]+u[l] * u[l+1]+u[l + 1] * u [L + 1] * u [L + 2] +.... u [l] ]∗u[l+1]∗....∗u[r])=1
Obviously, we can maintain interval multiplication with line tree. For example, we can directly maintain the product of u[1,r] and then divide it by the value of u[1,l+1]. Unfortunately, the accuracy of this problem card cannot be obtained in this way. Obviously, we can maintain interval multiplication with line tree. For example, we can directly maintain the product of u[1,r] and then divide it by u [1], Unfortunately, the accuracy of this problem card cannot be calculated in this way. Obviously, we can use line tree to maintain interval multiplication. For example, we can directly maintain the product of u[1,r] and divide it by the value of u[1,l+1]. Unfortunately, the accuracy of this problem card cannot be calculated in this way
We should consider how to merge interval information: for each node of line tree, it maintains an interval [l,r][l,r][l,r], we only look at one point, val1=u[l], two points are val2=u[l]+u[l]*u[l+1], three points are val3=u[l]+u[l] * u[l+1]+u[l+1] * u[l+2], assuming that the left son of line tree is [l,l+1], and the right son is [l+2], U [l] * u[l+1], three points are val3=u[l]+u[l]*u[l+1]+u[l]*u[l+1]*u[l+2], If the left son of the line tree is [l,l+1], and the right son is [l+2], then the combination is val2+val2 * u[l+2]=val3
Then we need to maintain two values in line tree: val=u[l]+u[l] * u[l+1]..., sum = u [l] * u[l+1]...; merging is valleftson+valleftson * sumrichson = valfather, sumleftson * sumrichson = sumpathserval = u [l] + u [l] * u[l+1]..., sum = u [l] * u[l+1]...; merging is val_+val_*sum_=val_,sum_*sum_=sum_val=u[l]+u[l] * u[l+1]..., sum = u [l] * u[l+1]...; merger is valleftson+valleftson * sumrichson = valfather, sumleftson * sumrichson = sumpath
Here's the code:
#include <iostream> #include <cstdio> #include <stack> #include <sstream> #include <vector> #include <map> #include <cstring> #include <deque> #include <cmath> #include <iomanip> #include <queue> #include <algorithm> #include <set> #define mid ((l + r) >> 1) #define Lson rt << 1, l , mid #define Rson rt << 1|1, mid + 1, r #define ms(a,al) memset(a,al,sizeof(a)) #define log2(a) log(a)/log(2) #define _for(i,a,b) for( int i = (a); i < (b); ++i) #define _rep(i,a,b) for( int i = (a); i <= (b); ++i) #define for_(i,a,b) for( int i = (a); i >= (b); -- i) #define rep_(i,a,b) for( int i = (a); i > (b); -- i) #define lowbit(x) ((-x) & x) #define Setw(a) fixed<<setprecision(a) #define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0) #define INF 0x3f3f3f3f #define hash Hash #define next Next #define count Count #define pb push_back #define f first #define s second using namespace std; const int N = 1e5+10, mod = 1e9 + 7; const double eps = 1e-10; typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair<int,int> PII; template<typename T> void read(T &x) { x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } template<typename T, typename... Args> void read(T &first, Args& ... args) { read(first); read(args...); } struct node { double x, w; }tr[N<<2]; int n, q; double a[N]; inline void pushup(int rt) { tr[rt].w = tr[rt << 1].w * tr[rt << 1|1].w; tr[rt].x = tr[rt << 1].x + tr[rt << 1].w * tr[rt << 1|1].x; return; } inline void build(int rt, int l, int r) { if(l == r) { tr[rt].x = a[l]; tr[rt].w = a[l]; return; } build(Lson);build(Rson); pushup(rt); } inline void update(int rt, int l, int r ,int pos, double val) { if(l == r) { tr[rt].w = val; tr[rt].x = val; return; } if(pos <= mid) update(Lson,pos,val); else update(Rson,pos,val); pushup(rt); } inline node query(int rt, int l, int r, int posl, int posr) { if(posl <= l && posr >= r) return tr[rt]; else { node left = (node){-INF,-INF}; node right = (node){-INF,-INF}; if(posl <= mid) left = query(Lson,posl,posr); if(posr > mid) right = query(Rson,posl,posr); if(left.w == -INF) return right; else if(right.w == -INF) return left; else { node res; res.w = left.w * right.w; res.x = left.x + left.w * right.x; return res; } } } int main() { read(n,q); _rep(i,1,n) { double l, r; cin >> l >> r; a[i] = 1.0 * l / r; a[i] = (1.0 - a[i]) / a[i]; } build(1,1,n); while(q--) { int op, pos; double l, r; read(op); if(op == 1) { cin >> pos >> l >> r; double ans = (1.0 - l/r) / (l/r); update(1,1,n,pos,ans); } else { cin >> l >> r; double ans = query(1,1,n,l,r).x; cout << Setw(10) << 1.0 / (ans + 1.0) << endl; } } return 0; }