zoukankan      html  css  js  c++  java
  • 51nod1836-战忽局的手段【期望dp,矩阵乘法】

    正题

    题目连接:http://www.51nod.com/Challenge/Problem.html#problemId=1836


    题目大意

    (n)个点(m)次随机选择一个点标记(可以重复),求最后被标记点的期望个数。

    (1leq n,mleq 10^{18})


    解题思路

    额开始拿方案数推了半天后面发现要斯特林数就放弃了,然后换了种方法发现很简单?

    (i)轮之后被标记点的期望个数是(f_i),那么有

    [f_i=f_{i-1}+frac{n-f_{i-1}}{n} ]

    [f_i=f_{i-1}frac{n-1}{n}+1 ]

    然后矩阵乘法就好了。

    有一说一我第一次用期望值来算概率(((

    时间复杂度(O(Tlog n))


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int S=2;
    struct Matrix{
    	__float128 a[S][S];
    }f,ans,c;
    long long T,n,m;
    Matrix operator*(const Matrix &a,const Matrix &b){
    	c.a[0][0]=c.a[0][1]=c.a[1][0]=c.a[1][1]=0;
    	for(int i=0;i<S;i++)
    		for(int j=0;j<S;j++)
    			for(int k=0;k<S;k++)
    				c.a[i][j]+=a.a[i][k]*b.a[k][j];
    	return c;
    }
    int main()
    {
    	scanf("%lld",&T);
    	while(T--){
    		scanf("%lld%lld",&n,&m);
    		f.a[1][1]=(__float128)(n-1)/n;
    		f.a[0][1]=f.a[0][0]=1;f.a[1][0]=0;
    		ans.a[0][0]=1;ans.a[0][1]=0;
    		while(m){
    			if(m&1)ans=ans*f;
    			f=f*f;m>>=1;
    		}
    		printf("%.12lf
    ",(double)ans.a[0][1]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    orm添加表记录
    创建多表模型
    包的使用
    日志写法
    os模块,是通过和操作系统交互进行操作
    sys python解释器做交互
    软件开发规范
    模块 time模块 datatime模块 random模块
    装饰器
    装饰器进阶
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15087088.html
Copyright © 2011-2022 走看看