快速幂
用二进制的处理方式
#include<iostream>
using namespace std;
typedef unsigned long long ull;
ull qmi(int a,int k,int p)
{
int res=1;
while(k)
{
if(k&1)res=(ull)res*a%p;//k末尾
k>>=1;//k移位
a=(ull)a*a%p;//a更新
}
return res;
}
int main()
{
int n;
cin>>n;
while(n--)
{
int a,k,p;
cin.tie(0);
ios::sync_with_stdio(false);
cin>>a>>k>>p;
cout<<qmi(a,k,p)<<endl;
}
return 0;
}
求组合数
方法一:递推法
关键公式:
C(n,0)=1
2000
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MOD=1e9+7;
const int N = 2010;
int c[N][N];
void init()
{
for(int i=0;i<N;i++)
{
for(int j=0;j<=i;j++)
{
if(j==0)c[i][j]=1;
else c[i][j]=(c[i-1][j]+c[i-1][j-1])%MOD;
}
}
}
int T;
int main()
{
init();
cin>>T;
while(T--)
{
int n,m;
scanf("%d%d", &n, &m);
printf("%d\n",c[n][m]);
}
return 0;
}
递推的一个例子211. 计算系数 - AcWing题库
这个数据范围比较小
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010, MOD = 10007;
int a, b, k, n, m;
int C[N][N];
int main()
{
scanf("%d%d%d%d%d", &a, &b, &k, &n, &m);
for (int i = 0; i <= k; i ++ )
for (int j = 0; j <= i; j ++ )
if (!j) C[i][j] = 1;
else C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
int res = C[k][n];
a %= MOD, b %= MOD;//这里的a m b n不能分开取模,如果分开取模,结果是错的
for (int i = 0; i < n; i ++ ) res = res * a % MOD;
for (int i = 0; i < m; i ++ ) res = res * b % MOD;
printf("%d\n", res);
return 0;
}