@
目录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]即可使用
目前遇到的大部分用法只有
标签:return,gcd,求解,数论,代码,小节,long,int From: https://www.cnblogs.com/linghusama/p/17397396.html