逆元的补充

题目描述

A和B在玩石头剪刀布的游戏(0代表石头,1代表剪刀,2代表布),他们进行了n场游戏,现在A知道B每场的情况,赢一场得一分,输和平不得分,问A最终得分为S的情况有多少种?
输入

第一行输入N和S,N表示进行N场游戏,S表示A的得分。(1≤N,S≤105)

第二行输入N个数(0,1,2),表示B每场的情况。
输出

输出有多少中情况使的A得分为S,数字很大,需要对答案取模109+7


样例输入

3 1
0 1 2

样例输出

12

题目链接https://oj.ismdeep.com/contest/problem?id=1555&pid=1

思路:由题目可以的出解为Cn,s 2^n-s%mod
但是由于无法做到整除所以必须把A/B变为A
C形式
根据费马小定理得:当A与mod互质时,B^mod-2次方就是B的逆元,即C;
所以有以下代码:

扫描二维码关注公众号,回复: 5798815 查看本文章
#include "bits/stdc++.h"
#define ll long long
int mod=1000000007;
using namespace std;
ll f(ll a,ll b)
{
  ll sum=1;
  while(b>0)
  {
    if(b&1)
    {
      sum=(sum*a)%mod;
    }
    a=a*a%mod;
    b>>=1;
  }
  return sum;
}
ll f1(int n,int s)
{
  ll sum=1;
  for(int i=1,j=n;i<=s;i++,j--)
  {
    sum=((sum*j)%mod*f(i,mod-2)%mod)%mod;//f(i,mod-2)就是j/i%mod=1时i的逆元
  }
  return sum;
}
int main(int argc, char const *argv[]) {
  int n,s;
  cin>>n>>s;
  int a;
  for(int i=0;i<n;i++)
  {
    cin>>a;
  }
  cout<<f(2,n-s)*f1(n,s)%mod<<endl;
  return 0;
}

**1.void exgcd(int a,int b,int &x,int &y)//求ax+by=gcd(a,b)得解x,y。
{
if(b==0)
{
x=1,y=0;return ;}
exgcd(b,a%b,x,y)

int tmp=x;
x=y;
y=tmp-(a/b)*y;
}
1.如果a,b互质即方程为ax+by=1; 当b==0则 ax=1;得出得x即为a得逆元;y为b的逆元

注:x,y是任意的

猜你喜欢

转载自blog.csdn.net/shuaizhijun/article/details/88981032