约数个数定理
若x=p1^a1*p2^a2*...*pn^an,(p1 p2 ... pn为素数)则约数个数为(p1+1)(p2+1)...(pn+1)
ll getnum(ll n) //得到a的约数个数.
{
ll res=1;
for(ll i=2;i*i<=n;i++){
ll k=0;
while(n%i == 0){
n = n/i;
k++;
}
if(k) res *= (k+1);
}
if(n != 1) res=res*2;
if(res==1){
if(n==1) return 1;
else return 2;
}
return res;
}
约数和定理
对于一个大于1正整数n可以分解质因数:x=p1^a1*p2^a2*p3^a3*…*pn^an,
f(n)=(p1^0+p1^1+p1^2+…p1^a1)(p2^0+p2^1+p2^2+…p2^a2)…(pk^0+pk^1+pk^2+…pk^an)
ll qpow(ll x, ll y )
{
ll res = 1;
while(y){
if(y&1) res *= x;
x *= x;
y >>= 1 ;
}
return res;
}
ll getsum(ll n) //返回n的约数和是多少.
{
ll res=1;
for(ll i=2;i*i<=n;i++){
ll k=0;
while(n%i == 0){
n = n/i;
k++;
}
res *= ((1-qpow(i,k+1))/(1-i));
} //用等比数列公式(快速幂)算.
if(n != 1) res *= (1 + n);
return res;
}
欧拉函数
求小于n的所有与n互质的数的个数
ll Euler(ll n) {
ll res = n;
for (ll i = 2; i*i <= n; i++) {
if (n%i == 0)
res = res / i*(i - 1);
while (n%i == 0)
n /= i;
}
if (n > 1)
res = res / n*(n - 1);
return res;
}
线性筛欧拉函数
const int maxn = 1e5+10;
int phi[maxn];//欧拉函数
int pri[maxn];//素数
bool vis[maxn];
int cnt=0;
int n;//求1->n所有欧拉函数
void getphi(){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){//如果是素数
phi[i]=i-1;//记录欧拉函数
pri[++cnt]=i;//记录素数
}
for(int j=1;j<=cnt;j++){
int x=pri[j];
if(i*x>n)break;
vis[i*x]=1;
if(i%x==0){
phi[i*x]=phi[i]*x;
break;
}
else
phi[i*x]=phi[i]*phi[x];
}
}
}
判断数x的在二进制下第j位是否为1
int x=3;
for(int j=0;j<2;j++){
if(x>>j&1)
cout<<"YES"<<endl;
}
裴蜀定理
方程ax+by=m有整数解时当且仅当m是gcd(a,b)的倍数
总结裴蜀定理:
若gcd(a,b)=d;
1. 则对于任意整数x,y,有ax+by一定是d的倍数
2. 一定存在整数x,y,使得ax+by=d成立
3. a,b互质(d==1)的充要条件是存在整数x,y使得ax+by=1
4. ax+by=m有解的条件时d|m
推广:对于n个整数,若gcd(a1,a2,…,an)=d;
1. 存在x1,x2…,xn,使得x1*a1+x2*a2+…+xn*an=d
2. a1…an互质(d==1)的充要条件是存在x1…xn使得x1*a1+…xn*an=1
3. x1*a1+…xn*an=m有解的条件是d|m
GCD的一个结论
gcd(a,b)=gcd(a,a-b) (a>b)
gcd(a,b)=gcd(a,b-a) (a<b)
附上一道例题:codeforces 1152C
GCD的一个性质
gcd(x1,x2,x3......xn)=gcd(x1,x2-x1,x3-x2......xn-xn-1)
二进制数枚举
//0-2^n
for(int i=0; i<(1<<n); i++)