X问题 HDU - 1573& Strange Way to Express Integers POJ - 2891
1. 题意
- 一个数模mi 等于 ai,第一个问题是求最小的,第二个问题是求x<=n有多少个
2. 分析
合并两个模数
假设
y=a1(mod m1)
y=a2(mod m2)
则有
x≡a1+t1∗m1(mod m1);1
x≡a2+t2∗m2(mod m2);2
t1∗m1−t2∗m2=a1−a2
利用欧几里得扩展求出 t1带入1 求出x
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;
}
1150

被折叠的 条评论
为什么被折叠?



