调和级数:1/1+2/1+3/1+...+1/n=log(n);
(准备好暴力了吗~~~)
1:[1,n]中k的倍数有多少个?
ans:(下取整)n/k;
2:[1,n]中每个数的约数有多少个?
for(int i=1;i<=n;i++)
for(int j=1;i*j<=n;j++)
ans[i*j]++;
调和级数原理:时间复杂度:O(log(n));
3:判断质数:
bool is_prim(int x)
{
if(x==1)return false;
for(int i=2;i*i<=x;i++)
if(x%i==0)return false;
return true;
}
两数互质:记作:a⊥b
4:
π(n)为不超过n的质数个数;
π(n)≈n/ln(n);
5:埃筛(nloglogn筛素数)
#include<bits/stdc++.h>
using namespace std;
int n,m;
bool isprim[10000005];
int endp;
int ls;
int main(){
scanf("%d%d",&n,&m);
memset(isprim,1,sizeof(isprim));
endp=sqrt(n);
isprim[1]=false;
for(int i=1;i<=endp;i++){
if(isprim[i])
for(int j=2;j*i<=n;j++)
isprim[j*i]=false;
}
for(int i=1;i<=m;i++){
scanf("%d",&ls);
if(isprim[ls])
printf("Yes
");
else
printf("No
");
}
return 0;
}
6:质因数分解
每一个数都可以唯一的分解成n个质数的k次方相乘的形式
int p[N]
int fenjie(int x)
{
int cnt=0;
for(int i=2;i*i<=x;i++){
while(x%i==0){
p[++cnt]=i;
x/=i;
}
}
if(x>1)p[++cnt]=x;
}
分解质因数后两数的乘除可转化成指数加减的形式
同时也可以用指数相减是否大于等于0判断一数能否整除另一数
一个数的因子数等于所有质因子的指数加一相乘后的结果(π)
7:随时取模
a=a/p(下取整)*p+a%p;
在只含加法减法和乘法的式子里如果最后的结果要对p取模,可以在式子里随便取模;
取模的最后结果可能出现负数:转化:((ans%p)+p)%p变为最小正值
每一个数都可以写成:a1*1+a2*10+a3*100。。。。的形式,由此可得出模数为三时a1+a2+a3。。。。%3=0即可得出原式%3=0
同样的只需a1*1+a2*10%4=0,即可得出原式%4=0;
8:gcd and lcm;
1:可用质因数分解求解(一般不用)
gcd(a,b)=gcd(b,a%b);
求解gcd:
void gcd(int a,int b)
{
if(b==0)return a;
return gcd(b,a%b);
}
求解lcm:
void lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
9:逆元
如果在%p的情况下除a和乘b所得结果相同,我们称a为b的逆元或b为a的逆元
inv(a)为a的逆元
inv(x)*x≡1(%p)
inv(a*b)=inv(a)*inv(b);
费马小定理:
若p为质数:
n^(p-1)≡1(%p)
n为任意正整数
so:
inv(x)*x≡x^(p-1)(%p)
两边同时除以x:
inv(x)≡x^(p-2)(%p)
只有a,b互质时a才在%b下存在逆元
裴蜀定理:
关于整数x,y的不定方程
ax+by=gcd(a,b)
必定有解
so:
我们知道
bx+(a%b)y=gcd(a,b)
求解
ax1+by1=gcd(a,b)
(x1,y1)=(y,x-a/b(下取整)*y)
扩展欧几里得(手推)
int x,y;
int ls;
void exgcd(int a,int b)
{
if(b==0){
x=1;
y=0;
return ;
}
exgcd(b,a%b);
ls=x;
x=y;
y=ls-a/b*y;
}
a即为%b意义下的逆元
来了来了!!!!
线性递推求模质数逆元:
inv[1]=1;
for(int i=2;i<p;i++)
inv[i]=(p-p/i)*inv[p%i]%p;
(p为质数,代码可求出在模p意义下1~p-1中所有数的逆元)
9.5:阶乘逆元
求组和数:
定义:fac[x]表示(x!)%p;
{
fac[0]=1;
for(int i=1;i<p;i++)
fac[i]=fac[i-1]*i%p;
}
inv[x]表示x!在模p意义下的逆元
{
1:利用线性递推求模质数的逆元
inv[0]=inv[1]=1;
for(int i=2;i<p;i++)
inv[i]=(p-p/i)*inv[p%i]%p;
for(int i=1;i<p;i++)
inv[i]=inv[i-1]*inv[i]%p;
2:exgcd求解
利用exgcd求解n!的逆元
然后利用inv[n-1]=inv[n]*n;
递推求解
}
so:c(m,n)=fac[n]*inv[m]%p*inv[n-m]%p;
10:线性同余方程
中国剩余定理(CRT)
x≡a1(%m1)
x≡a2(%m2)
x≡a3(%m3)
……
x≡an(%mn)
ans%(M)=∑(i=1;i<=n;i++)ai*inv mi (Mi)*Mi ;: (Mi=a1*a2*a3*…*an/ai),M(m1*m2*m3*…*mn);
ans有无数个,每M个中有一个满足条件
11:排列组合;
为什么不看看数学书呢?
组合数: 公式递推代码 C(n, m) = C(n -1, m - 1) + C(n - 1, m) (pascal公式)
模意义下:lucas定理:c(n,m)=c(n/p,m/p)*c(n%p,m%p)%p;(p为质数):log(n)求解
c(0,0)=1;
12:杂项
有个类似分治的办法算快速幂和快速乘(为什么不看看书呢?)
现在有n个正整数,需要从中取出k个数,使得他们的gcd最大,求这个gcd;
从大到小枚举,在输入时记录n[x],当n[gcd]+n[2*gcd]+n[3*gcd]+…+n[n*gcd]>=k时满足条件
由于调和级数,最后的时间复杂度为nlog(n);
可能想不起来:
(1):不等式;
(2):1+2+3+…+n=n*(n+1)/2;
1^2+2^2+3^2+…+n^2=n*(n+1)*(2*n+1)/6;
1^3+2^3+3^3+…+n^3=[n(n+1)/2]^2
13:欧拉函数:
φ(x):小于x的与x互质的正整数的个数
φ(x)=x*π(连乘符号)(1-1/p);(p为x的质因子)
若a⊥b那么φ(a*b)=φ(a)*φ(b);
线性筛素数andφ:
https://www.cnblogs.com/grubbyskyer/p/3852421.html
欧拉定理:
哼唧,不证