西安赛区 B-Coin

感觉还是做的题目少了,列出二项式之后就只想着怎么快速求组合数公式了,看了别人的博客才知道可以通过矩阵来做。(参考博客:http://blog.csdn.net/qq_33951440/article/details/78005483)矩阵的【1】【1】(即矩阵的第一行第一列)代表偶数次的概率,矩阵的【1】【2】代表奇数次的概率。

#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;

typedef long long ll;
const int maxn=3;
struct Matrix 
{
	ll a[maxn][maxn];
	void init()
	{
		memset(a,0,sizeof(a));
		for(int i;i<maxn;i++)
		{
			a[i][i]=1;
		}
	}
};
const ll mod=1e9+7;
Matrix mul(Matrix a,Matrix b) //a*b &mod(*没有用矩阵快速幂)
{
	Matrix ans;
	memset(ans.a,0,sizeof(ans.a));
	int i,j;
	for(i=1;i<maxn;i++)
	{
		for(j=1;j<maxn;j++)
		{
			ans.a[i][j]=0;
			for(int k=1;k<maxn;k++)
			{
				ans.a[i][j]+=a.a[i][k]*b.a[k][j];//!是+=
				ans.a[i][j]%=mod;
			}
		}
	}
	return ans;
}
Matrix pow(Matrix a,ll m)//* a^m 矩阵快速幂
{
	Matrix res;
	memset(res.a,0,sizeof(res.a));
	int i;
	for(i=1;i<maxn;i++)
	{
		res.a[i][i]=1;
	}
	while(m)
	{
		if(m&1)
			res=mul(a,res);//res=a*res;
		a=mul(a,a);//a*a;
		m>>=1;
	}
	return res;
}

ll quick(ll n,ll m)//n^m %mod 快速幂
{
	ll ans=1;
	while(m)
	{
		if(m&1)
			ans=ans*n%mod;
		n=n*n%mod;
		m>>=1;
	}
	return ans;
}

int main()
{
	//double p;
	int t=0;
	int n;
	scanf("%d",&t);
	while(t--)
	{
		ll p,q,k;
		scanf("%lld%lld%lld",&p,&q,&k);
		ll nums=q*quick(p,mod-2)%mod;//* q*p^(mod-2) %mod 即q*p逆
//(看到mod-2 就觉得可能是求逆元,这种法子求逆元,就想到是不是互素,看了下题目没说,搜了下才发现,网上有关于为什么要对1e9+7取模,里面提到有个很大且好记的质数1e9+7(包括它的孪生素数1e9+9)
		ll numx=(p-q)*quick(p,mod-2)%mod;//(p-q)*p逆
		Matrix ans;
		ans.a[1][1]=(numx)%mod;
		ans.a[2][1]=(nums)%mod;

		if(k==1)
		{
			printf("%lld\n",ans.a[1][1]%mod);//(p-q)*p^-1
			continue;
		}
		Matrix base,res;
		base.a[1][1]=numx,base.a[1][2]=nums;
		base.a[2][1]=nums,base.a[2][2]=numx;
		res=pow(base,k-1);//base矩阵的k-1次方
		ans=mul(base,res);//相当于ans=base的k次方
		printf("%lld\n",ans.a[1][1]%mod);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值