模线性方程
X问题 http://acm.hdu.edu.cn/showproblem.php?pid=1573
用无要求的中国剩余定理求解模线性方程组,当然这个题也有暴力的做法,详情请见nenu contest2
1 #include<cstdio> 2 const int M=16; 3 int a[M],b[M]; 4 int gcd(int a,int b) { //最大公约数 5 return b?gcd(b,a%b):a; 6 } 7 int lcm(int a,int b) { //最小公倍数 8 return a/gcd(a,b)*b; 9 } 10 int ext_gcd(int a,int b,int &x,int &y) { //扩展gcd d=gcd(a,b)=a*x+b*y; return d,x,y; 11 int t,ret; 12 if(!b) { 13 x=1; 14 y=0; 15 return a; 16 } 17 ret=ext_gcd(b,a%b,x,y); 18 t=x; 19 x=y; 20 y=t-a/b*y; 21 return ret; 22 } 23 int modular_linear_system(int a[],int b[],int n){//求解模线性方程组(无要求)X mod a[i]=b[i],n个方程 24 int m1,m2,r1,r2,c,d,t,x,y; 25 m1=a[0]; 26 r1=b[0]; 27 for(int i=1;i<n;i++){ 28 m2=a[i]; 29 r2=b[i]; 30 c=r2-r1; 31 d=ext_gcd(m1,m2,x,y); 32 if(c%d) return -1; 33 t=m2/d; 34 x=(c/d*x%t+t)%t; 35 r1=m1*x+r1; 36 m1=m1*m2/d; 37 } 38 return r1; 39 } 40 int main() { 41 int t,n,m; 42 while(~scanf("%d",&t)) { 43 while(t--) { 44 scanf("%d%d",&n,&m); 45 int sumlcm=1; 46 for(int i=0; i<m; i++) { 47 scanf("%d",&a[i]); 48 sumlcm=lcm(sumlcm,a[i]); 49 } 50 for(int i=0; i<m; i++) { 51 scanf("%d",&b[i]); 52 } 53 int ans=modular_linear_system(a,b,m); 54 if(ans==-1||ans>n) { 55 puts("0"); 56 continue; 57 } 58 if(ans==0) ans+=sumlcm; 59 int sum=(n-ans)/sumlcm+1; 60 printf("%d\n",sum); 61 } 62 } 63 return 0; 64 }
Strange Way to Express Integers http://poj.org/problem?id=2891
同上,更简单,模板题。
1 #include<cstdio> 2 typedef __int64 LL; 3 const int M=1024; 4 LL ext_gcd(LL a,LL b,LL &x,LL &y) { //扩展gcd d=gcd(a,b)=a*x+b*y; return d,x,y; 5 LL t,ret; 6 if(!b) { 7 x=1; 8 y=0; 9 return a; 10 } 11 ret=ext_gcd(b,a%b,x,y); 12 t=x; 13 x=y; 14 y=t-a/b*y; 15 return ret; 16 } 17 LL modular_linear_system(LL a[],LL b[],LL n){//求解模线性方程组(无要求)X mod a[i]=b[i],n个方程 18 LL m1,m2,r1,r2,c,d,t,x,y; 19 m1=a[0]; 20 r1=b[0]; 21 for(int i=1;i<n;i++){ 22 m2=a[i]; 23 r2=b[i]; 24 c=r2-r1; 25 d=ext_gcd(m1,m2,x,y); 26 if(c%d) return -1; 27 t=m2/d; 28 x=(c/d*x%t+t)%t; 29 r1=m1*x+r1; 30 m1=m1*m2/d; 31 } 32 return r1; 33 } 34 LL a[M],b[M]; 35 int main(){ 36 int n; 37 while(~scanf("%d",&n)){ 38 for(int i=0;i<n;i++){ 39 scanf("%I64d%I64d",&a[i],&b[i]); 40 } 41 printf("%I64d\n",modular_linear_system(a,b,n)); 42 } 43 return 0; 44 }
Hello Kiki http://acm.hdu.edu.cn/showproblem.php?pid=3579
看了别人的才知道要特判一个并且整除。其实就是最小解如果是零的话,那就应该加上所有ai的lcm,找到第一个正整数解。
1 #include<cstdio> 2 const int M=8; 3 int ext_gcd(int a,int b,int &x,int &y) { //扩展gcd d=gcd(a,b)=a*x+b*y; return d,x,y; 4 int t,ret; 5 if(!b) { 6 x=1; 7 y=0; 8 return a; 9 } 10 ret=ext_gcd(b,a%b,x,y); 11 t=x; 12 x=y; 13 y=t-a/b*y; 14 return ret; 15 } 16 int modular_linear_system(int a[],int b[],int n){//求解模线性方程组(无要求)X mod a[i]=b[i],n个方程 17 int m1,m2,r1,r2,c,d,t,x,y; 18 m1=a[0]; 19 r1=b[0]; 20 for(int i=1;i<n;i++){ 21 m2=a[i]; 22 r2=b[i]; 23 c=r2-r1; 24 d=ext_gcd(m1,m2,x,y); 25 if(c%d) return -1; 26 t=m2/d; 27 x=(c/d*x%t+t)%t; 28 r1=m1*x+r1; 29 m1=m1*m2/d; 30 } 31 return r1; 32 } 33 int a[M],b[M]; 34 int main(){ 35 int t,n; 36 while(~scanf("%d",&t)){ 37 for(int cas=1;cas<=t;cas++){ 38 scanf("%d",&n); 39 for(int i=0;i<n;i++){ 40 scanf("%d",&a[i]); 41 } 42 for(int i=0;i<n;i++){ 43 scanf("%d",&b[i]); 44 } 45 int ans; 46 if(n==1&&!b[0]){ 47 ans=a[0]; 48 } 49 else{ 50 ans=modular_linear_system(a,b,n); 51 } 52 printf("Case %d: %d\n",cas,ans); 53 } 54 } 55 return 0; 56 }
end