一、快速幂函
求a的b次方,如果b很大,那么执行效率就是很低,可以利用 a^(2b) = a^b 乘以a^b进行优化。

#include<iostream>
using namespace std;
int Pow(int a,int b)
{
if(b == 0)
return 1;
if(b&1)
return a*Pow(a,b-1);
else{
int t = Pow(a,b/2);
return t*t;
}
}
int main()
{
int a,b;
while(cin>>a>>b)
{
cout<<Pow(a,b)<<endl;
}
}
//非递归
#include<iostream>
using namespace std;
int Pow(int a,int b)
{
int result = 1;
int base = a;
while(b){
if(b&1)
result *= base;
base *= base;
b /= 2;
}
return result;
}
int main()
{
int a,b;
while(cin>>a>>b){
cout<<Pow(a,b)<<endl;
}
}
二、快速幂取模
如果先求a^b,再进行求余,当b很大时效率会很低。根据公式(a*b)mod c = [(a mod c) * (b mod c)] mod c以及快速幂可以进行优化。

#include<iostream>
using namespace std;
int PowMod(int a,int b,int c)
//(a^b)mod c
{
int result = 1;
int base = a%c;
while(b)
{
if(b&1) //幂为奇数时的操作,结果乘以基数(因为奇数时可能是b=1,操作后为输出结果)
result = (result*base)%c;
base = (base*base)%c;
b /=2;
}
return result;
}
int main()
{
int a,b,c;
while(cin>>a>>b>>c)
{
cout<<PowMod(a,b,c)<<endl;
}
}
三、等比数列二分求和取模
S n = a+a 2 +...+a n
要求 S n mod p
如果用公式算,可能溢出,因此用二分法求
1) 若 n 是偶数
S n = a+...+a n/2 + a n/2+1 + a n/2+2 +...+ a n/2+n/2
=(a+...+a n/2 ) + a n/2 (a+...+a n/2 )
=S n/2 + a n/2 S n/2
=(1+a n/2 )S n/2
2) 若n 是奇数
S n = a+...+a (n-1)/2 + a (n-1)/2+1 +...
+ a (n-1)/2+(n-1)/2 + a (n-1)/2+(n-1)/2 + 1
=S (n-1)/2 + a (n-1)/2 (a+...+a (n-1)/2 )+a n
=(1+a (n-1)/2 )S (n-1)/2 +a n
结合公式:( a+b)mod c = ( (a mod c) + (b mod c) ) mod c;
附:运用递归关系的三个条件
1、可以把要解决的问题转化为一个新问题,而这个新的问题的解决方法仍与原来的解决方法相同,只是所处理的对象有规律地递增或递减。
2、可以应用这个转化过程使问题得到解决。
3、必定要有一个明确的结束递归的条件。
#include<iostream>
using namespace std;
int PowMod(int a,int b,int c)
{
int result = 1;
int base = a%c;
while(b)
{
if(b&1)
result = (result * base)%c;
base = (base * base)%c;
b /= 2;
}
return result;
}
int PowSumMod(int a,int n,int p)
{
if(n == 1)
return a%p;
else{
if(n%2 == 0)
return (1 + PowMod(a,n/2,p) ) * PowSumMod(a,n/2,p) % p;
else
return ((1 + PowMod(a,(n-1)/2,p)) * PowSumMod(a,(n-1)/2,p) + PowSumMod(a,n,p) ) % p;
}
}
int main()
{
int a,n,p;
while(cin>>a>>n>>p)
{
cout<<PowSumMod(a,n,p)<<endl;
}
}
四、线性筛法求素数
求给定范围内的所有素数。
为了防止重复删数,进行改写得:
#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int>prime;
vector<bool>is_prime(n+1);
for(int i = 1;i <= n;i++){
is_prime[i] = true;
}
for(int i = 2;i <= n;i++){
if(is_prime[i])
prime.push_back(i);
for(int j = 0;j < prime.size();j++){
if(i*prime[j] <= n)
is_prime[i*prime[j]] = false;
else
break;
}
}
for(int i = 0;i < prime.size(); ++i)
cout << prime[i] << endl;
return 0;
}
1031

被折叠的 条评论
为什么被折叠?



