CF712Eメモリとカジノの期待、見直しの可能性

トピックリンク

CF712Eメモリとカジノ

\(まず\) はじめに

この質問は黒偽のタイトル・トラックであります

I Aの前に学校の兄弟のグループは、私があまりにも弱かったです

私たちの考えはの首長から派生する必要がありますczpcf

その式は非常に性急な推進している自己と思います

だから私は別のものを書くことにしました

\(第二\) アイデア

定義\(F(i、j)は \) カジノから(私は\)\カジノで始まる\は(私は\)カジノで勝つ\(J \)優勝と終了の確率を

定義\(F(J + 1、 k)は\) カジノから\(J \) + 1は、カジノで始まる\(J \)カジノで+ 1勝\(K \)を受賞し、終了する確率

定義された\(G(i、j)は \) と\(F \)が、逆に

だから、\(F(I、K)\) =直接過去の確率(ここでは真ん中にもラップを回しませんが、決して持っていたかもしれ行く\(J \を))+サークルの真ん中順番にをし、確率(円の真ん中に渡りました\(J \)

行く直接過去の確率= \(F(I、J)* F(J + 1、k)は\)

円の中央ターンにおける確率を越えて行く= \(F(I、J)* F(J + 1、K)\) * \(\ DisplayStyle \ SUM ^ {+ \ inftyの} _ {P = 1} W ^ P \)

前記\(W \)は、中間革命の確率で

フォーカスがされて(\ w)は\カウントする方法

\(W \) = \((1-F(j + 1、k))を(1-G(i、j)の)\)

この式は、それが来る方法ですか?

ことを理解すべきで\(1-F(j + 1、k)が\)

カジノから\(J \)カジノで始まる+ 1 \(J \)カジノで+ 1勝\(K \)を受賞し、終了する確率

ここでは\(1-F(J + 1、k)は\)

カジノ\(J \) + 1は、デフォルトの開始であります

唯一の条件

  • 1:カジノで\(J \) + 1勝

  • 2:カジノで\(K \)勝利

2中の少なくとも一つが満たされていません

しかし、エンドに\(2 \)の結果は、右の間隔(関係なく、彼女のから復帰する予定です\([J + 1、K ] \) どのように多くの周回ターン)

\(さらに\) 簡素化

\ [F(I、K)\]

\ [^ Pの\ W = F(i、j)はF *(J + 1、K)\ displaystyle \和^ {+ \ inftyの} _ {P = 1}]

\ [= F(i、j)はF *(J + 1、K)\ FRAC {1-W ^ {+ \ inftyの}} {1-W} \]

\ [^ {A + \ inftyの} = 0 \]

\ [\ RIGHTARROW = \ FRAC {F(i、j)はF *(J + 1、K)}、{1-(1-F(j + 1、k))を(1-G(i、j)は)} \]

この時間は、ツリーラインを維持するために使用することができます

\(結局\) \(コード\)

#include <map>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define reg register int
#define isdigit(x) ('0' <= (x)&&(x) <= '9')
template<typename T>
inline T Read(T Type)
{
    T x = 0,f = 1;
    char a = getchar();
    while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
    while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();}
    return x * f;
}
#define fi first
#define se second
typedef double db;
const int MAXN = 100010;
db p[MAXN];
struct node
{
    double g,f;
}tree[MAXN << 2];
inline void sum(db &f,db &g,db f1,db f2,db g1,db g2)
{
    f = f1 * f2 / (1 - (1 - f2) * (1 - g1));
    g = g1 * g2 / (1 - (1 - f2) * (1 - g1));
}
inline void BuildTree(int k,int l,int r)
{
    if(l == r)
    {
        tree[k].f = p[l],tree[k].g = 1 - p[l];
        return;
    }
    int mid = l + r >> 1;
    BuildTree(k << 1,l,mid);
    BuildTree(k << 1 | 1,mid + 1,r);
    sum(tree[k].f,tree[k].g,tree[k << 1].f,tree[k << 1 | 1].f,tree[k << 1].g,tree[k << 1 | 1].g);
}
inline pair<db,db> query(int k,int l,int r,int L,int R)
{
    if(L <= l&&r <= R) return make_pair(tree[k].f,tree[k].g);
    int mid = l + r >> 1;
    pair<db,db> k1,k2;k1.fi = k2.fi = k1.se = k2.se = 1;
    if(L <= mid) k1 = query(k << 1,l,mid,L,R);
    if(mid < R) k2 = query(k << 1 | 1,mid + 1,r,L,R);
    db T1,T2;
    sum(T1,T2,k1.fi,k2.fi,k1.se,k2.se);
    return make_pair(T1,T2);
}
inline void update(int k,int l,int r,int pos,db x)
{
    if(l == r)
    {
        tree[k].f = x,tree[k].g = 1 - x;
        return;
    }
    int mid = l + r >> 1;
    if(pos <= mid) update(k << 1,l,mid,pos,x);
    else update(k << 1 | 1,mid + 1,r,pos,x);
    sum(tree[k].f,tree[k].g,tree[k << 1].f,tree[k << 1 | 1].f,tree[k << 1].g,tree[k << 1 | 1].g);
}
int main()
{
    int n = Read(1),q = Read(1);
    for(reg i = 1;i <= n;i++)
    {
        int a = Read(1),b = Read(1);
        p[i] = (db)a / b;
    }
    BuildTree(1,1,n);
    while(q--)
    {
        int sit = Read(1);
        if(sit & 1)
        {
            int pos = Read(1),a = Read(1),b = Read(1);
            update(1,1,n,pos,((db)a / b));
        } else {
            int l = Read(1),r = Read(1);
            cout << query(1,1,n,l,r).fi << endl;
        }
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/resftlmuttmotw/p/11719396.html