您的位置:首页 > 其它

X问题 HDU - 1573& Strange Way to Express Integers POJ - 2891

2017-10-07 23:13 387 查看
X问题 HDU - 1573& Strange Way to Express Integers POJ - 2891

1. 题意

一个数模mimi 等于 aiai,第一个问题是求最小的,第二个问题是求x<=n有多少个

2. 分析

合并两个模数

假设

y=a1(mod m1)y=a1(mod m1)

y=a2(mod m2)y=a2(mod m2)

则有

x≡a1+t1∗m1(mod m1);1x≡a1+t1∗m1(mod m1);1

x≡a2+t2∗m2(mod m2);2x≡a2+t2∗m2(mod m2);2

t1∗m1−t2∗m2=a1−a2t1∗m1−t2∗m2=a1−a2

利用欧几里得扩展求出 t1t1带入1 求出xx

y=x(mod lcm(m1,m2))y=x(mod lcm(m1,m2))

3.参考代码

X问题 HDU - 1573

const int maxn = 100;
int aa[maxn];
int bb[maxn];
int N,M;
int  ex_gcd(int a,int b,int  &x,int  &y)
{
if(b==0)
{
x = 1;
y = 0;
return a;
}
LL c = ex_gcd(b,a%b,y,x);
y -= a/b*x;
return c;
}

int main(void)
{
int T;
cin>>T;

while(T--)
{
cin>>N>>M;
int A,B;
for(int i = 0; i < M; ++i)
cin>>aa[i];
for(int i = 0;i < M; ++i)
cin>>bb[i];
A = aa[0];
B = bb[0];
bool F = true;
for(int i = 1; i < M; ++i)
{
int  x,y;
int d = ex_gcd(A,aa[i],x,y);
int c = bb[i] - B;
if(c%d!=0)
{
F = false;
break;
}
c /= d;
x *= c;
aa[i] /= d;
x = (x%aa[i]+aa[i])%aa[i];
B = B + x * A;
A = A*aa[i];
B = (B%A+A)%A;
}
if(!F)
cout<<0<<endl;
else
{
if(B==0)
cout<<N/A<<endl;
else
cout<< N/A+((N-N/A*A)>=B?1:0)<<endl;
}

}

}


Strange Way to Express Integers POJ - 2891

using namespace std;

long long exgcd(long long m,long long n,long long &x,long long &y)
{
long long x1,y1,x0,y0;
x0=1; y0=0;
x1=0; y1=1;
x=0; y=1;
long long r=m%n;
long long q=(m-r)/n;
while(r)
{
x=x0-q*x1; y=y0-q*y1;
x0=x1; y0=y1;
x1=x; y1=y;
m=n; n=r; r=m%n;
q=(m-r)/n;
}
return n;
}

int main()
{
int n;
long long a1,r1,a2,r2,c,d,x,y;
bool flat;
while(scanf("%d",&n)!=EOF)
{
flat=false;
scanf("%lld%lld",&a1,&r1);
for(int i=1;i<n;i++)
{
scanf("%lld%lld",&a2,&r2);
if(flat)continue;
c=r2-r1;
d=exgcd(a1,a2,x,y);
if(c%d)
{
flat=true;
continue;
}
x*=c/d;
a2/=d;
x=(x%a2+a2)%a2;
r1=r1+x*a1;
a1*=a2;
}
if(flat)puts("-1");
else printf("%lld\n",r1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  欧几里得扩展