一、快速幂
递归写法
int quickpow(int a,int b,int c)
{
if(b==1) return a%n;
int t=quickpow(a,b/2,c)%n;
t=t*t%n;
if(b%2==0) return t;
else return t*a%n;
}
非递归写法
int quickpow(int a,int b,int n)
{
int ret=1;
while(b)
{
if(b%2==1) ret=ret*a%n;
a=a*a%n;
b/=2;
}
}
二、求n的正约数集合
(1)求n的正约数集合:试除法O(sqrt(N))
int v[N],m=0;
for(int i=1;i*i<=n;++i)
{
if(n%i==0)
{
v[++m]=i;
if(i!=n/i) v[++m]=n/i;
}
}
(2)求1~n中所有正整数的正约数集合(倍数法)O(NlogN)
vector<int> q[N];
for(int i=1;i<=n;++i)
for(int j=1;j<=n/i;++j)
v[i*j].push_back(i);
三、gcd
(1)求a,b的最大公因数即gcd(a,b)
很短
int gcd(int a,int b)
{
return b ? gcd(b,a%b) : a;
}
(2)exgcd
裴蜀定理:
对于任意整数a、b,存在一对整数x、y,满足ax+by=gcd(a,b);
性质1:对于ax+by=c(c<=gcd(a,b)),只有c=gcd(a,b)时才有解
c>gcd(a,b)时很明显有无数多组解
void exgcd(int a,int b,int &d,int &x,int &y)
{
if(b==0)
{
d=a,x=1,y=0;
return;
}
exgcd(b,a%b,d,x,y);
int t=x;x=y;
y=t-a/b*y;
}