exgcd写错成功爆0:)
Input
第一行一个整数T,表示需要求解的方程数。
接下来T 行,每行三个整数:a; b; c 表示一个方程:
ax + by = c
Output
对于每个方程:
• 如果方程无解,输出No
• 如果方程有解,输出四个整数:x1 y1 x2 y2,表示两组解,其中x1 y1 表示x 是最小非负时对应的
解,其中x2 y2 表示y 是最小非负时的解。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
long long t,x,y;
long long gcd(long long m,long long n)
{
if (n==0)
return m;
return gcd(n,m%n);
}
long long exgcd(long long a,long long b,long long &x,long long &y)
{
long long cd;
if (b==0)
{
x=1;
y=0;
return a;
}
else
{
long long x0,y0;
cd=exgcd(b,a%b,x0,y0);
x=y0;
y=x0-(a/b)*y0;
}
return cd;
}
int main()
{
freopen("modeq.in","r",stdin);
freopen("modeq.out","w",stdout);
scanf("%I64d",&t);
while (t--)
{
long long a,b,c;
scanf("%I64d%I64d%I64d",&a,&b,&c);
long long d=gcd(a,b);
if (c%d!=0)
{
printf("No\n");
continue;
}
else
{
exgcd(a,b,x,y);
long long x1=c/d*x;
long long y1=c/d*y;
long long x2=c/d*x;
long long y2=c/d*y;
x1=(x1%abs(b/d)+abs(b/d))%abs(b/d);
y1=(c-a*x1)/b;
printf("%I64d %I64d ",x1,y1);
y2=(y2%abs(a/d)+abs(a/d))%abs(a/d);
x2=(c-y2*b)/a;
printf("%I64d %I64d\n",x2,y2);
}
}
return 0;
}
我们来个孙子定理完整版。
可能现在还来不起。。。我们就先假设mi 两两互质吧。
Input
第一行一个整数T,表示需要求解的方程组数。
接下来T 个方程组,对于每个方程组:
第1 行一个整数n,表示方程组对应的方程个数。
接下来n 行,第i 行两个数:ai mi 表示第i 个方程:
x ai (mod mi)
Output
对于每个方程:输出最小非负整数解。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
long long t,n;
vector<long long> vm;
vector<long long> va;
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 x1,y1;
long long cd=exgcd(b,a%b,x1,y1);
x=y1;
y=x1-(a/b)*y1;
return cd;
}
long long ins(long long num,long long mod)
{
long long x,y;
exgcd(num,mod,x,y);
return (x%mod+mod)%mod;
}
long long crt(vector<long long> va,vector<long long> vm)
{
long long x=0;
long long len=(long long)va.size();
long long M=1;
for (int i=0;i<len;i++)
M*=vm[i];
for (int i=0;i<len;i++){
long long ci=M/vm[i];
long long ny=ins(ci,vm[i]);
x=(x+va[i]*ny%M*ci%M)%M;
}
return x;
}
int main()
{
freopen("crt.in","r",stdin);
freopen("crt.out","w",stdout);
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
va.clear();
vm.clear();
for (int i=1;i<=n;i++)
{
long long aa,mm;
scanf("%I64d%I64d",&aa,&mm);
va.push_back(aa);
vm.push_back(mm);
}printf("%I64d\n",crt(va,vm));
}
return 0;
}
我们来个递推精简版。求下面数列的第n 项:
f(0) = a0; f(1) = a1; f(2) = a2
f(n) = bf(n