codeforce Gym 100425E The Street Escalator(期望,线性递推)

算数学期望,每个人都可以分开来考虑。Xi表示第i个人跑到另外一边的次数。

Xi服从二项分布。概率的和是个二项式,(p+1-p)^T,把二项式展开,p的偶次项是留在原来那一边的概率。

可以用((a+b)^T+(a-b)^T)/2来算出偶次项之和。

也可以用矩阵快速幂。矩阵构造如下

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
//#include<bits/stdc++.h>
using namespace std;

typedef double MType;
const int maxn = 1e5+5;

struct Person
{
    double p;
    char side;
    int T;
    void IN(){
        scanf("%d %c %lf",&T,&side,&p);
    }
    void cal(MType &lft, MType &rgh){
        double keep = (1+pow(1-2*p,T))/2;
        if(side == 'L') lft = keep, rgh = 1-keep;
        else lft = 1-keep, rgh = keep;
    }
}P;

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    int N; scanf("%d",&N);
    MType L = 1, R = 0, ans = 0;
    for(int i = 0; i < N; i++){
        P.IN();
        MType l,r;
        P.cal(l,r);
        ans += L*l + R*r;
        L = r;
        R = l;
    }
    printf("%.12lf",ans);
    return 0;
}

快速幂

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
//#include<bits/stdc++.h>
using namespace std;

const int MSIZE = 2, n = 2;
typedef double MType;
struct Matrix
{
    MType dat[MSIZE][MSIZE];
    MType *operator [](int x){ return dat[x]; }
    Matrix operator * (Matrix& B) {
        Matrix re;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                re[i][j] = 0;
                for(int k = 0; k < n; k++){
                    re[i][j] += dat[i][k]*B[k][j];
                }
            }
        }
        return re;
    }
    Matrix operator ^ (int q){
        Matrix Re, A = *this;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                Re[i][j] = i == j?1:0;
            }
        }
        while(q){
            if(q&1){
                Re = Re * A;
            }
            A = A * A;
            q >>= 1;
        }
        return Re;
    }
};

const int maxn = 1e5+5;
struct Person
{
    double p;
    char side;
    int T;
    void IN(){
        scanf("%d %c %lf",&T,&side,&p);
    }
    void cal(MType &lft, MType &rgh){
        Matrix C;
        C[0][0] = C[1][1] = 1-p;
        C[0][1] = C[1][0] = p;
        C = C^T;
        if(side == 'L') lft = C[0][0], rgh = C[1][0];
        else lft = C[0][1], rgh = C[1][1];
    }
}P[maxn];

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    int N; scanf("%d",&N);
    for(int i = 0; i < N; i++){
        P[i].IN();
    }
    //sort(P,P+N);
    MType L = 1, R = 0, ans = 0;
    for(int i = 0; i < N; i++){
        MType l,r;
        P[i].cal(l,r);
        ans += L*l + R*r;
        L = r;
        R = l;
    }
    printf("%.12lf",ans);
    return 0;
}

 

posted @ 2015-10-18 19:52  陈瑞宇  阅读(309)  评论(0编辑  收藏  举报