HDU-2669-Romantic(扩欧一组x最小解)
题意: 给定a,b,求出方程ax+by=1的解,x是最小的非负数。
通解为:x=x+bt y=y– at.
#include<iostream>
#include<algorithm>
#define en '\n'
using namespace std;
typedef long long ll;
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1,y=0;
return a;
}
ll tmp=ex_gcd(b,a%b,x,y);
ll r=x;
x=y,y=r-a/b*y;
return tmp;
}
int main()
{
ll a,b,x,y;
while(~scanf("%lld%lld",&a,&b))
{
ll ans=ex_gcd(a,b,x,y);
if(ans!=1) puts("sorry");
else
{
ll r=x,t;
x=((x%b)+b)%b;
t=(r-x)/b,y+=t*a;
printf("%lld %lld\n",x,y);
}
}
}
POJ-2115-C Looooops(扩欧)
题意: 对于C的for(i=A ; i!=B ;i +=C)循环语句,问在k位存储系统中循环几次才会结束。若在有限次内结束,则输出循环次数。否则输出死循环。
题意不难理解,只是利用了 k位存储系统 的数据特性进行循环。例如int型是16位的,那么int能保存2^ 16个数据,即最大数为65535(本题默认为无符号),当循环使得i超过65535时,则i会返回0重新开始计数。如i=65534,当i+=3时,i=1。其实就是i=(65534+3)%(2^16)=1。
//输入A B C L
//原方程:(A+k*C)%mod=B; A+k*C=Y*mod+B;
//转化方程:C*k-mod*Y=B-A;
//ex_gcd(C,mod,k,Y) mod=quick_pow(2,L);
#include<iostream>
#include<algorithm>
#define en '\n'
using namespace std;
typedef long long ll;
const int M=5e5+5,N=4e4+5;
ll quick_pow(ll c,ll p)
{
ll res=1;
while(p)
{
if(p&1) res*=c;
c*=c,p>>=1;
}
return res;
}
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1,y=0;
return a;
}
ll tmp=ex_gcd(b,a%b,x,y);
ll r=x;
x=y,y=r-a/b*y;
return tmp;
}
int main()
{
ll A,B,C,L,x,y;
while(~scanf("%lld%lld%lld%lld",&A,&B,&C,&L),A||B||C||L)
{
L=quick_pow(2,L);
ll ans=ex_gcd(C,L,x,y);
if((B-A)%ans) puts("FOREVER");
else
{
x*=(B-A)/ans;
ll mod=L/ans;
printf("%lld\n",(x%mod+mod)%mod);
}
}
}
//原始方程:(n-m)*x+b-a=k*L
//转化方程:(n-m)*x+k*L=a-b
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1,y=0;
return a;
}
ll tmp=ex_gcd(b,a%b,x,y),r;
r=x,x=y,y=r-a/b*y;
return tmp;
}
int main()
{
ll a,b,c,d,L;scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&L);
ll x,y,ans;
ans=ex_gcd(d-c,L,x,y);
if((a-b)%ans) puts("Impossible");
else
{
ll r=L/ans;
x*=(a-b)/ans;
printf("%lld\n",((x%r)+r)%r);
}
}