在C/C++中,+,-的优先级低于/,*,%,而/,*,%优先级一样,所以就从左到右
1.乘法
我们在做题的时候,遇到(a*b)%c,由于可能a*b先计算的话,会超精度,所以我们可以这么转化
(a*b)%c = (a%c)*(b%c)%c
2.加法或减法
(a+b)%c =( (a%c)+(b%c) )%c
3.除法
我们一般遇到除法
(a/b)%MOD的时候,会将除法变为乘法,用到了
“逆元”的思想
什么是逆元:
当求解公式:(a/b)%m 时,因b可能会过大,会出现爆精度的情况,所以需变除法为乘法:
设c是b的逆元,则有b*c≡1(mod m);
则(a/b)%m = (a/b)*1%m = (a/b)*b*c%m = a*c(mod m);
即a/b的模等于a*
b的逆元的模;
逆元就是这样应用的;
如何求逆元:
一个简单的方法,用
小费马定理,具体不讲,就讲如何计算,先找一个素数,一般题目给出的最后答案需要对某个数(1e9+7)进行求模,这个数刚好就是素数,所以就用这个MOD
那么对于某个数的逆元,如
b的逆元就是b^(MOD-2),这个计算就用到了
快速幂来计算。
所以对于:
(a/b)%MOD = %MOD
这样子就把除法的求模运算,变成了乘法的求模运算
4.大指数——欧拉降幂(具体会模板,知道怎么用)
当遇到,比如10^100000,指数爆炸的时候就要降幂,因此需要用到“欧拉降幂”,具体原理可点击:
欧拉函数与欧拉降幂
直接讲结论和代码模板(要结合快速幂),根据一道题来:
FZU 1759
简单题意就是,A^B mod C,其中B很大,B<10^100000,那么这个指数就会爆炸,所以就要利用欧拉降幂,代码中phi()函数表示欧拉函数,quickpow()函数表示快速幂。
代码如下:
#include
#include
#include
#define ll __int64
#define mod 10000000007
using namespace std;
char a[1000006];
ll x,z;
ll quickpow(ll x,ll y,ll z)
{
ll ans=1;
while(y)
{
if(y&1)
ans=ans*x%z;
x=x*x%z;
y>>=1;
}
return ans;
}
ll phi(ll n)
{
ll i,rea=n;
for(i=2;i*i<=n;i++)
{
if(n%i==0)
{
rea=rea-rea/i;
while(n%i==0)
n/=i;
}
}
if(n>1)
rea=rea-rea/n;
return rea;
}
int main()
{
while(scanf("%I64d %s %I64d",&x,a,&z)!=EOF)
{
ll len=strlen(a);
ll p=phi(z);
ll ans=0;
for(ll i=0;i