定义g(x),为x的约数个数
对于一个数i,可分解成若干质数幂次的乘积,即
i=prime[1]a∗prime[2]b∗.....
g(i)=(a+1)∗(b+1)∗..... .
a|b b|c => a|c
a|b a|c => a|bc
a|b a|c => a|ib±jc (a|b,c的线性组合)
a|b b|a => a=±b
a=ib±c => 公因子(a,b)=公因子(b,c)
function gcd(a,b:longint):longint;
begin
if b=0
then gcd:=a
else gcd:=gcd(b,a mod b);
end;
function gcd(a,b:longint):longint;
begin
if a=0 then exit(b)
else
if b=0 then exit(a)
else
if a=b then exit(a);
if a mod 2=0
then
if b mod 2=0
then gcd:=2*gcd(a div 2,b div 2)
else gcd:=gcd(a div 2,b)
else
if b mod 2=0
then gcd:=gcd(a,b div 2)
else
if a>b
then gcd:=gcd(b,a-b)
else gcd:=gcd(b,b-a);
end;
求不定方程 a∗x+b∗y=1 的一组解的方法
由 a∗x1+b∗y1=gcd(a,b)=gcd(b,amod b)=b∗x2+[a−⌊a/b⌋∗b]∗y2=a∗y2+b∗(x2−y2∗⌊a/b⌋)
=>x1=y2
procedure exgcd(a,b:int64;var d,x,y:int64);
var t:int64;
begin
if b=0
then
begin d:=a; x:=1; y:=0; end
else
begin exgcd(b,a mod b,d,x,y); t:=x; x:=y; y:=t-y*(a div b); end;
end;
利用扩展欧几里得算法求解不定方程 a∗x+b∗y=n 的整数解的求解全过程,步骤如下:
(1)先计算 Gcd(a,b) ,若n不能被 Gcd(a,b) 整除,则方程无整数解;否则,在方程两边同时除以 Gcd(a,b) ,得到新的不定方程 a2∗x+b2∗y=n2 此时 Gcd(a2,b2)=1;
(2)利用扩展欧几里德算法求出方程 a2∗x+b2∗y=1 的一组整数解 x0,y0 ,则 n2∗x0,n2∗y0是方程a2∗x+b2∗y=n2的一组整数解;
(3)根据数论中的相关定理,可得方程 a2∗x+b2∗y=n2 的所有整数解为:
x=n2∗x0+b2∗t
y=n2∗y0−a2∗t (t=0,1,2,……)
调整得到正整数解
function f(a,b,n:int64):int64; //(a^b) mod n
var t,y:int64;
begin
t:=1;
y:=a;
while b<>0do
begin
if(b and 1)=1
then t:=t*y mod n;
y:=y*y mod n;
b:=b shr 1;
end;
exit(t);
end;
矩阵乘法求斐波那契数列
[F[N−1]F[N]]=[acbd]⋅[F[N−2]F[N−1]]
{F[N−1]=a⋅F[N−2]+b⋅F[N−1] F[N]=c⋅F[N−2]+d⋅F[N−1]
⎧⎩⎨⎪⎪⎪⎪a=0b=1c=1d=1
[F[N−1]F[N]]=[0111]⋅[F[N−2]F[N−1]]
[F[N−1]F[N]]=[0111]N−1⋅[F[0]F[1]]
var
x:array[0..100000000]of longint;
i,j,k,n:longint;
t,y:array[1..2,1..2]of int64;
function g(f:longint):longint;
var a,b,c,d:longint;
begin
t[1,1]:=1; t[1,2]:=0; t[2,1]:=0; t[2,2]:=1;
y[1,1]:=0; y[1,2]:=1; y[2,1]:=1; y[2,2]:=1;
k:=1000000007;
while f<>0 do
begin
if (f and 1)=1
then begin
a:=(t[1,1]*y[1,1]+t[1,2]*y[2,1])mod k;
b:=(t[1,1]*y[1,2]+t[1,2]*y[2,2])mod k;
c:=(t[2,1]*y[1,1]+t[2,2]*y[2,1])mod k;
d:=(t[2,1]*y[1,2]+t[2,2]*y[2,2])mod k;
t[1,1]:=a mod k; t[1,2]:=b mod k; t[2,1]:=c mod k; t[2,2]:=d mod k;
end;
a:=(y[1,1]*y[1,1]+y[1,2]*y[2,1])mod k;
b:=(y[1,1]*y[1,2]+y[1,2]*y[2,2])mod k;
c:=(y[2,1]*y[1,1]+y[2,2]*y[2,1])mod k;
d:=(y[2,1]*y[1,2]+y[2,2]*y[2,2])mod k;
y[1,1]:=a mod k; y[1,2]:=b mod k; y[2,1]:=c mod k; y[2,2]:=d mod k;
f:=f shr 1;
end;
exit((x[1]*t[2,1]+x[0]*t[2,2])mod k);
end;
begin
readln(n);
k:=1000000007;
x[0]:=1; x[1]:=1;
writeln(g(n-1));
for i:=2 to n do
x[i]:=(x[i-1]+x[i-2])mod k;
writeln(x[n]);
end.
例如 a[n]=a[n−1]+a[n−2]+5
⎡⎣⎢a[N−1]a[N]1⎤⎦⎥=⎡⎣⎢110100501⎤⎦⎥⋅⎡⎣⎢a[N−2]a[N−1]1⎤⎦⎥
var
prime:array[0..3562115]of longint;
check:array[0..60000000]of boolean;
i,j:longint;
n,len:longint;
begin
readln(n);
for i:=2 to n do
begin
if check[i]=false
then begin inc(len); prime[len]:=i; end;
for j:=1 to len do
begin
if i*prime[j]>n then break;
check[i*prime[j]]:=true;
if i mod prime[j]=0 then break;
end;
end;
writeln(len);
for i:=1 to len do
write(prime[i]);
end.
我们知道对于一个的他的因子的大小不超过 N−−√ ,所以线性筛预处理,再取模判断即可
const
maxn=1000000;
var
check:array[0..maxn]of boolean;
phi,prime:array[0..maxn]of longint;
n,i,j,ans,len:longint;
begin
readln(n);
len:=0;
for i:=2 to n do
begin
if check[i]=false
then begin inc(len); phi[i]:=i-1; prime[len]:=i; end;
for j:=1 to len do
begin
if prime[j]*i>n
then break;
check[i*prime[j]]:=true;
if i mod prime[j]=0
then begin phi[i*prime[j]]:=phi[i]*prime[j]; break; end
else phi[i*prime[j]]:=phi[i]*(prime[j]-1);
end;
end;
for i:=1 to n do
writeln(phi[i]);
end.
const
maxn=1006350;
var
check:array[0..maxn]of boolean;
prime:array[0..maxn]of longint;
i,j:longint;
n,s,ans,len,t:longint;
begin
readln(n);
s:=n; ans:=n; n:=trunc(sqrt(n)); len:=0;
for i:=2 to n do
begin
if check[i]=false
then begin inc(len); prime[len]:=i; end;
for j:=1 to len do
begin
if prime[j]*i>n
then break;
check[prime[j]*i]:=true;
if i mod prime[j]=0
then break;
end;
end;
for i:=1 to len do
begin
if s mod prime[i]=0
then
begin
ans:=(ans div prime[i])*(prime[i]-1);
while s mod prime[i]=0 do
s:=s div prime[i];
end;
end;
if s<>1
then ans:=(ans div s)*(s-1); //1700016764
writeln(ans);
end.
const
maxn=100000;
var
check:array[0..maxn]of boolean;
mu,prime:array[0..maxn]of longint;
i,j,len,n:longint;
begin
readln(n); mu[1]:=1; len:=0;
for i:=2 to n do
begin
if check[i]=false
then begin mu[i]:=-1; inc(len); prime[len]:=i; end;
for j:=1 to len do
begin
if i*prime[j]>n
then break;
check[i*prime[j]]:=true;
if i mod prime[j]=0
then begin mu[i*prime[j]]:=0; break; end
else mu[i*prime[j]]:=-mu[i];
end;
end;
for i:=1 to n do
writeln(i,' ',mu[i]);
end.
中国剩余定理可以求解模数互质的情况,但根据ydc的课件,我们用其他方式合并
求逆元的方法汇总