您的位置:首页 > 其它

51nod 1836:战忽局的手段

2017-02-20 16:32 302 查看
51nod 1836:战忽局的手段

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1836

矩阵快速幂

从题目所给的数据范围来看复杂度应该为O(1)或者O(lgn),于是定义ƒ(x)为n个事件,x次忽悠下的期望事件数

很明显可以得到这样一个递推式:ƒ(x)=ƒ(x-1)+[1-ƒ(x-1)/n]=1+(1-1/n)ƒ(x-1)

于是我们就可以构造矩阵以O(lgn)的复杂度来解这道题啦。

/*注意这道题卡精度,可以用__float128来保存中间变量减少精度丢失*/

代码如下:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
ll T,n,m;
struct matrix{
__float128 mp[2][2];
friend matrix operator * (matrix a,matrix b){
matrix t;
for(int i=0;i<2;++i)
for(int j=0;j<2;++j){
t.mp[i][j]=0;
for(int k=0;k<2;++k)
t.mp[i][j]+=a.mp[i][k]*b.mp[k][j];
}
return t;
}
}E,A;
matrix pow(matrix A,ll n){
matrix base=A,ans=E;
while(n){
if(n&1)ans=ans*base;
base=base*base;
n>>=1;
}
return ans;
}
int main(void){
E.mp[0][0]=E.mp[1][1]=1;
E.mp[0][1]=E.mp[1][0]=0;
scanf("%lld",&T);
while(T--){
scanf("%lld%lld",&n,&m);
A.mp[0][0]=(__float128)1-(__float128)1/(__float128)n;A.mp[0][1]=1;
A.mp[1][0]=0;A.mp[1][1]=1;
matrix temp=pow(A,m-1);
double ans=(double)(temp.mp[0][0]+temp.mp[0][1]);
printf("%.7lf\n",ans);
}
}


当然也可以将递推式继续推算下去,以O(1)的复杂度解决。(数据小的话直接用math.h,否则直接取极限)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: