快速幂
计算ab%m时如果a,b的数值过大直接计算可能会溢出,这种情况就要用到快速幂。
快速幂的迭代写法:
#define ll long long
ll a,b,m;
ll ans = 1;
while(b){
if(b&1)
ans = ans * a % m;
a = a * a % m; //得到a平方
b = b >> 1;
}
计算快速幂的过程如下图:
以a13为例
b | b&1 | a | ans |
---|---|---|---|
1 | |||
1101 | 1 | a | a |
110 | 0 | a2 | a |
11 | 1 | a4 | a5 |
1 | 1 | a8 | a13 |
快速乘
计算a*b%m
#define ll long long
ll a,b,m;
ll ans = 1;
while(b){
if(b&1)
ans = (ans + a) % m;
a = a << 1 % m;//将a乘以2
b = b >> 1;
}
计算快速乘的过程如下图:
以a*13为例
b | b&1 | a | ans |
---|---|---|---|
0 | |||
1101 | 1 | a | a |
110 | 0 | 2a | a |
11 | 1 | 4a | 5a |
1 | 1 | 8a | 13a |
例题
输入n,计算从1到n的和,结果对1e+7取余。
数据规模:n <= 1018。
代码:
#include<cstdio>
#define ll long long
const ll mod = 1e9+7;
int main(void){
ll n;
scanf("%lld",&n);
ll a,b;
if(n % 2 == 0){
a = n / 2 % mod;
b = (n + 1) % mod;
}else{
a = (n + 1) / 2 % mod;
b = n % mod;
}
ll ans = 0;
while(a){
if(b&1)
ans = (ans + a) % mod;
a = a<<1 % mod;
b = b>>1;
}
printf("%lld",ans);
return 0;
}