描述
求 a 乘 b 对 p 取模的值,其中 1≤a,b,p≤10^18。
输入格式
第一行a,第二行b,第三行p。
输出格式
一个整数,表示a*b mod p的值。
样例输入
2
3
9
样例输出
6
快速幂的思想。a*b=ck*a*2^k+…………c0*a*2^0;
求出(a*2^k-1)%p,再乘2是不超过long long的类型的。
#include <cstdio>
#include <string>
#include<list>
#include<cstring>
#include<iostream>
#include<cmath>
typedef long long ll;
#define M 1000000
using namespace std;
int main()
{
ll a,b,p;
cin>>a>>b>>p;
ll ans=0,k=1;
while(b>=1)
{
if(b&1)
ans=(a+ans)%p;
a=a*2%p;
b>>=1;
// cout<<ans%p<<endl;
}
cout<<ans%p<<endl;
return 0;
}
//126348976 982638476 938420413
//701649771
还有一种骚操作,利用long double和long long 舍弃位数的原理进行我们想要的操作;
a*b%p=a*b-(a*b/p)【向下取整】*p;
a*b long long超出范围后会舍弃掉高位,但我们只需知道差值就行,差值一定在0-p之间,舍弃不会影响差的值。
而a*b/p*p,这个操作让a取long double 会用科学记数法,保留有效数字。这个是足够用的,因为我们是向下取整,本来小数部分就不用考虑,。。
好强的操作!!!!
#include <cstdio>
#include <string>
#include<list>
#include<cstring>
#include<iostream>
#include<cmath>
typedef long long ll;
#define M 1000000
using namespace std;
int main()
{
ll a,b,p;
cin>>a>>b>>p;
ll ans=0,k=1;
a%=p,b%=p;
ll c=(long double)a*b/p;
ans=a*b-c*p;
cout<<ans<<endl;
return 0;
}
//126348976 982638476 938420413
//701649771
人一我百,人百我万。夕林山寸,寻梦指尖!