拓展欧几里得 专题

时间:2021-09-04 16:04:58

大神orz(具体参考请点这)

我根据个人感觉弄了一下自己的思路

 

ZOJ 3609 :http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4712 求最小逆元,坑点就是对m=1的特判

 

/**************************************************************
Problem:zoj 3609
User: youmi
Language: C++
Result: Accepted
Time:0s
Memory:272kb
***************************************************************
*/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include
<cstdio>
#include
<cstring>
#include
<algorithm>
#include
<map>
#include
<stack>
#include
<set>
#include
<sstream>
#include
<cmath>
#include
<queue>
#include
<deque>
#include
<string>
#include
<vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef
long long ll;

ll exgcd(ll a,ll b,ll
&x,ll &y)
{
if(b==0)
{
x
=1,y=0;
return a;
}
ll ans
=exgcd(b,a%b,x,y);
ll temp
=x;
x
=y;
y
=temp-a/b*y;
return ans;
}

int main()
{
freopen(
"in.txt","r",stdin);
int T_T;
scanf(
"%d",&T_T);
for(int kase=1;kase<=T_T;kase++)
{
ll a,mod;
scanf(
"%lld%lld",&a,&mod);
ll x,y;
ll ans
=exgcd(a,mod,x,y);
if(1%ans)
printf(
"Not Exist\n");
else
printf(
"%lld\n",(x%mod+mod)%mod+(mod==1));
}
return 0;
}

 

ZOJ 3593 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3593 求最小的步数,等价于求解方程:

ax+by=gcd,(A-B)%gcd==0。

又因为要求最小步数,所以,

根据x = x0 + (b/gcd)*t,y = y0 – (a/gcd)*t

我们可以推断当x==y时,步数是最小的,

即y0-x0=t*(a+b)/gcd→t=(y0-x0) / ((a+b)/gcd),

这样t的范围也就确定了。最后,如果x,y同号,取最大;如果异号,则做差

 

/**************************************************************
Problem:zoj 3593
User: youmi
Language: C++
Result: Accepted
Time:0ms
Memory:272kb
***************************************************************
*/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include
<cstdio>
#include
<cstring>
#include
<algorithm>
#include
<map>
#include
<stack>
#include
<set>
#include
<sstream>
#include
<cmath>
#include
<queue>
#include
<deque>
#include
<string>
#include
<vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo (1ll<<31)
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef
long long ll;
ll ex_gcd(ll a,ll b,ll
&x,ll &y)
{
if(b==0)
{
x
=1,y=0;
return a;
}
ll gcd
=ex_gcd(b,a%b,x,y);
ll temp
=x;
x
=y;
y
=temp-a/b*y;
return gcd;
}
int main()
{
//freopen("in.txt","r",stdin);
int T_T;
scanf(
"%d",&T_T);
for(int kase=1;kase<=T_T;kase++)
{
ll A,B,a,b;
scanf(
"%lld%lld%lld%lld",&A,&B,&a,&b);
ll x,y;
ll len
=B-A;
ll gcd
=ex_gcd(a,b,x,y);
if(len%gcd==0)
{
a
=a/gcd,b=b/gcd;
x
*=len/gcd,y*=len/gcd;
ll m
=(y-x)/(a+b);
ll ans
=1ll*oo*oo,temp;
for(ll t=m-1;t<=m+1;t++)
{
if(abs(x+b*t)+abs(y-a*t)==abs(x+b*t+y-a*t))
temp
=Max(abs(x+b*t),abs(y-a*t));
else
temp
=abs(x-y+(a+b)*t);
ans
=Min(temp,ans);
}
printf(
"%lld\n",ans);
}
else
printf(
"-1\n");
}
return 0;
}

POJ 1061 http://poj.org/problem?id=1061 青蛙的约会,由题意得:(mk+x)%L==(nk+y)%L,所以

(m-n)k+L*t=gcd,(x-y)%gcd==0.。。。。。。。

/**************************************************************
Problem:poj 1061
User: youmi
Language: C++
Result: Accepted
Time:0ms  
Memory:140kb
***************************************************************
*/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include
<cstdio>
#include
<cstring>
#include
<algorithm>
#include
<map>
#include
<stack>
#include
<set>
#include
<sstream>
#include
<cmath>
#include
<queue>
#include
<deque>
#include
<string>
#include
<vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef
long long ll;
ll ex_gcd(ll a,ll b,ll
&x,ll &y)
{
if(b==0)
{
x
=1,y=0;
return a;
}
ll gcd
=ex_gcd(b,a%b,x,y);
ll temp
=x;
x
=y;
y
=temp-a/b*y;
return gcd;
}

int main()
{
//freopen("in.txt","r",stdin);
ll A,B,a,b,l;
while(~scanf("%lld%lld%lld%lld%lld",&A,&B,&a,&b,&l))
{
ll x,y;
ll gcd
=ex_gcd(a-b,l,x,y);
ll len
=B-A;
if(len%gcd==0)
{
x
*=len/gcd;
l
=abs(1.0*l/gcd);
x
%=l;
if(x<=0)
x
+=l;
printf(
"%lld\n",x);
}
else
printf(
"Impossible\n");
}
return 0;
}

 

HDU 1576 http://acm.hdu.edu.cn/showproblem.php?pid=1576 由题意可得:A=Bx,A=n+9973y;所以回归到我们的经典方程可得:

Bx+9973y=gcd,n%gcd==0。。

/**************************************************************
Problem:hdu 1576
User: youmi
Language: C++
Result: Accepted
Time:0ms
Memory:1548kb
***************************************************************
*/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include
<cstdio>
#include
<cstring>
#include
<algorithm>
#include
<map>
#include
<stack>
#include
<set>
#include
<sstream>
#include
<cmath>
#include
<queue>
#include
<deque>
#include
<string>
#include
<vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef
long long ll;
ll ex_gcd(ll a,ll b,ll
&x,ll &y)
{
if(b==0)
{
x
=1,y=0;
return a;
}
ll gcd
=ex_gcd(b,a%b,x,y);
ll temp
=x;
x
=y;
y
=temp-a/b*y;
return gcd;
}
void cal(ll a,ll b,ll c)
{
ll x,y;
ll gcd
=ex_gcd(a,b,x,y);
x
*=c/gcd;
b
=abs(1.0*b/gcd);
x
%=b;
if(x<=0)
x
+=b;
ptlld(x);
}
int main()
{
//freopen("in.txt","r",stdin);
int T_T;
scanf(
"%d",&T_T);
for(int kase=1;kase<=T_T;kase++)
{
ll n,b;
scanf(
"%I64d%I64d",&n,&b);
cal(b,
9973,n);
}
return 0;
}

HDU 2669 http://acm.hdu.edu.cn/showproblem.php?pid=2669 这个是裸的欧几里得不为过,不过好好利用ax+by=1会使思路更加明晰

/**************************************************************
Problem:
User: youmi
Language: C++
Result: Accepted
Time:
Memory:
***************************************************************
*/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include
<cstdio>
#include
<cstring>
#include
<algorithm>
#include
<map>
#include
<stack>
#include
<set>
#include
<sstream>
#include
<cmath>
#include
<queue>
#include
<deque>
#include
<string>
#include
<vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef
long long ll;
ll ex_gcd(ll a,ll b,ll
&x,ll &y)
{
if(b==0)
{
x
=1,y=0;
return a;
}
ll gcd
=ex_gcd(b,a%b,x,y);
ll temp
=x;
x
=y;
y
=temp-a/b*y;
return gcd;
}
ll cal(ll a,ll b,ll c)
{
ll x,y;
ll gcd
=ex_gcd(a,b,x,y);
if(c%gcd)
return -1;
x
*=c/gcd;
b
=abs(1.0*b/gcd);
x
%=b;
if(x<=0)
x
+=b;
return x;
}
int main()
{
//freopen("in.txt","r",stdin);
ll a,b;
while(~scanf("%I64d%I64d",&a,&b))
{
ll ans
=cal(a,b,1);
if(ans==-1)
printf(
"sorry\n");
else
printf(
"%I64d %I64d\n",ans,(1-ans*a)/b);
}
return 0;
}

 poj 2115 http://poj.org/problem?id=2115 A+XC==B(MOD 2^K)

拓展欧几里得 专题拓展欧几里得 专题
/**************************************************************
Problem:
User: youmi
Language: C++
Result: Accepted
Time:0MS
Memory:712K
***************************************************************
*/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include
<cstdio>
#include
<cstring>
#include
<algorithm>
#include
<map>
#include
<stack>
#include
<set>
#include
<sstream>
#include
<cmath>
#include
<queue>
#include
<deque>
#include
<string>
#include
<vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef
long long ll;
ll ex_gcd(ll a,ll b,ll
&x,ll &y)
{
if(b==0)
{
x
=1,y=0;
return a;
}
ll ans
=ex_gcd(b,a%b,x,y);
ll temp
=x;
x
=y;
y
=temp-y*(a/b);
return ans;
}
void solve(ll a,ll b,ll c)
{
ll x,y;
ll d
=ex_gcd(a,b,x,y);
if(c%d!=0)
{
printf(
"FOREVER\n");
return ;
}
ll t
=b/d;
x
=(x*(c/d)%t+t)%t;
printf(
"%lld\n",x);
}
int main()
{
//freopen("in.txt","r",stdin);
ll a,b,c,k;
while(~scanf("%lld%lld%lld%lld",&a,&b,&c,&k)&&(a+b+c+k))
{
solve(c,1ll
<<k,b-a);
}
return 0;
}
@我