数论小节
Posted linghusama
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论小节相关的知识,希望对你有一定的参考价值。
@
目录
1.exgcd
前提:gcd函数代码:
long long gcd(long long a,long long b)
return b>0?gcd(b,a%b):a;
函数代码:
long long exgcd(long long a,long long b,long long&x,long long &y)
if(b==0)
x=1,y=0;
return a;
long long d=exgcd(b,a%b,x,y);
long long t=x;
x=y;
y=t-a/b*y;
return d;
使用格式:
long long x,y,m,n,l;
long long X,Y;
long long x0;
cin >> x >>y>>m>>n>>l;//解x+tm%l=y+tn%l的t ____x-y+tm-tn=kl(k,t正整数)
long long a=m-n;//(m-n)x0-ly0=y-x 求x0最小正整数
long long b=-l;
long long c=y-x;
x0=exgcd(a,b,X,Y);//返回gcd
if(c%x0!=0)//无解
cout<<"Impossible";
else
b=b/x0;
cout<<((X*(c)/x0)%b+b)%b;
适用模式:
1.求解方程
解决形如ax+by=c的方程式
2.欧拉函数
函数代码:
int phi(int x)
int ans=x;
int i;
for(i=2;i*i<=x;i++)
if(x%i==0)
ans=ans/i*(i-1);
while(x%i==0)
x/=i;
if(x>1)
ans=ans/x*(x-1);
return ans;
使用格式:
直接用phi(x);
适用模式:
1.求解方程
对形如
$$
a^x mod k \\equiv 1
$$
的x求解———>先求phi(k),再枚举它的因子
2.求解有限制的gcd
不太好说,上例子
//-----------------------------------------重点在这后面
int ans=0;
// for(int i=0;i<=ma;i++)
//// if(gcd(i,m)==1)
//// ans++;
////
// //用欧拉函数代替一下
ans=phi(ma);
//----------------------------------------重点在这前面
说白了就是把一堆gcd(i,m),m为定值的和进行o(1)求解
3.(ex)BSGS
函数代码:
long long BSGS(long long a,long long b,long long p,long long v=1)
if(!a)
if(!b) return 1;
else return -1;
long long m =ceil(sqrt(p)),val=1,d;
for(long long i=0;i<m;++i)
long long pron=b*val%p;
MP[pron]=i;
val=val*a%p;
d=v*val%p;
for(long long i=1;i<=m;++i)
if(MP.count(d))
long long res=MP[d];
return i*m-res;
d=d*val%p;
return -1;
long long exbsgs(long long a,long long b,long long p)
if (b==1||p==1)return 0;
long long t,c=0,v=1;
while((t=gcd(a,p))!=1)
if(b%t)
return -1;
else
p/=t;
b/=t;
v=v*a/t%p;
++c;
if(b==v)
return c;
long long ret=BSGS(a,b,p,v);
return ret!=-1?ret+c:ret;
使用格式:
直接套用即可
适用范围:
1.求解方程组
$$
a^x\\equiv b(mod p)
$$
4.整数分块
代码:
long long fd
long long res=0;
for(int l=1,r;l<=n;l=r+1)
r=n/(n/l);
用法:
1.简化时间复杂度
2.其中每一段,每一段的个数有r-l+1个,值为n/l;
5.莫比乌斯反演(思想)
代码:
m[1] = 1;
for(int i = 2; i <= n; i++)
if(!k[i])
p[++t] = i;
m[i] = -1;
for(int j = 1; j <= t && p[j]*i <= n; j++)
k[p[j]*i] = 1;
if(i%p[j] == 0) break;
m[i*p[j]] = -m[i];
用法:
直接用m[x]即可使用
目前遇到的大部分用法只有
到处都是本章小节,读研意义何在?
以上是关于数论小节的主要内容,如果未能解决你的问题,请参考以下文章