欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

51nod1836-战忽局的手段【期望dp,矩阵乘法】

发布时间:2023/12/3 编程问答 67 豆豆
生活随笔 收集整理的这篇文章主要介绍了 51nod1836-战忽局的手段【期望dp,矩阵乘法】 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

正题

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


题目大意

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

1≤n,m≤10181\leq n,m\leq 10^{18}1n,m1018


解题思路

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

iii轮之后被标记点的期望个数是fif_ifi,那么有
fi=fi−1+n−fi−1nf_i=f_{i-1}+\frac{n-f_{i-1}}{n}fi=fi1+nnfi1
fi=fi−1n−1n+1f_i=f_{i-1}\frac{n-1}{n}+1fi=fi1nn1+1
然后矩阵乘法就好了。

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

时间复杂度O(Tlog⁡n)O(T\log n)O(Tlogn)


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\n",(double)ans.a[0][1]);}return 0; }

总结

以上是生活随笔为你收集整理的51nod1836-战忽局的手段【期望dp,矩阵乘法】的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。