题目描述
给定 n 组询问,每组询问给定三个整数 a,b,p,其中 p 是质数,请你输出 Cbamodp 的值。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一组 a,b,p。
输出格式
共 n 行,每行输出一个询问的解。
数据范围
1≤n≤20,
1≤b≤a≤1018,
1≤p≤105,
样例
输入样例:
3
5 3 7
3 1 5
6 4 13
输出样例:
3
3
2
算法1
(卢卡斯定理) $O(f(p)+g(n)*log n)$
对于质数p,有:
对于C(a mod p,b mod p)部分,因为a mod p和b mod p均小于p,所以可以直接用定义去求
对于C(a/p,b/p)部分,因为其数字依旧可能很大,所以递归使用lucas来求
边界条件:当b=0时返回1;
时间复杂度
参考文献
lucas定理证明可见 https://oi-wiki.org/math/number-theory/lucas/
有帮助的话点个赞😊
C++ 代码
#include<iostream>
using namespace std;
typedef long long ll;
int p;
int qmi(int a,int k)
{
int res=1;
while(k)
{
if(k&1)res=(ll)res*a%p;
a=(ll)a*a%p;
k>>=1;
}
return res;
}
int C(ll a,ll b)
{
int res=1;
for(int i=1,j=a;i<=b;i++,j--)
{
res=(ll)res*j%p;
res=(ll)res*qmi(i,p-2)%p;
}
return res;
}
int lucas(ll a,ll b)
{
if(a<p&&b<p)return C(a,b);
return (ll)C(a%p,b%p)*lucas(a/p,b/p)%p;
}
int main()
{
int n;
cin>>n;
while(n--)
{
ll a,b;
cin>>a>>b>>p;
cout<<lucas(a,b)<<endl;
}
return 0;
}
算法2
(暴力枚举) $O(n^2)$
blablabla
时间复杂度
参考文献
C++ 代码
blablabla