模线性方程模板
View Code
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef __int64 int64; int64 A,B,C,K; int64 p[35]; void get_P() { p[0]=1; for(int i=1;i<33;i++) p[i]=p[i-1]*2; } int64 Extend_euc(int64 a,int64 b,int64&x,int64&y) { if(b==0) { x=1, y=0; return a; } int64 d,tmp; d=Extend_euc(b,a%b,x,y); tmp=x; x=y; y=tmp-(a/b)*y; return d; } void solve() { int64 i,j,k,d,x,y,ans; int64 tmp=B-A; d=Extend_euc(C,p[K],x,y); if(tmp%d) puts("FOREVER"); else { ans=(tmp/d*x)%p[K]+p[K]; printf("%I64d\n",ans%(p[K]/d)); } } int main() { get_P(); while(scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&K),A+B+C+K) solve(); return 0; }
扩展 GCD: 求x, y使得gcd(a, b) = a * x + b * y;
View Code
/*=======================================*\ 扩展GCD:求x, y使得gcd(a, b) = a * x + b * y; \*=======================================*/ int Extend_euc(int a,int b,int&x,int&y) { if(b==0) { x=1, y=0; return a;} int d=Extend_euc(b,a%b,x,y); int tmp=x; x=y; y=tmp-(a/b)*y; return d; }
模线性方程 a * x = b (% n)
View Code
/*=====================================*\ | 模线性方程 a * x = b (% n) \*=====================================*/ void modeq(int a, int b, int n) {// !n>0 int e,i,d,x,y; d=extgcd(a,n,x,y); if(b%d > 0) puts("No answer!"); else { e = (x*(b/d))%n; for(i=0; i<d; i++) // !!! here x maybe < 0 printf("%d-th ans: %d\n",i+1,(e+i*(n/d))%n); } }
中国余数定理 其中r, a已知,a[i]>0且a[i]与a[j]互质, 求ans;
View Code
/*==================================================*\ | 模线性方程组 | ans=r[1](% a[1]); ans=r[2](% a[2]); ... ans=r[N](% a[N]); | 其中r, a已知,a[i]>0且a[i]与a[j]互质, 求ans; (中国余数定理) \*==================================================*/ void china() { int64 i,j,k; int64 a1,r1,a2,r2,d,x,y,tmp; bool flag=true; scanf("%I64d%I64d",&a1,&r1); for(i=1;i<N;i++) { scanf("%I64d%I64d",&a2,&r2); if(!flag) continue; tmp=r2-r1; d=Extend_euc(a1,a2,x,y); if(tmp%d) {flag=false;r1=-1;continue;} //无解 r1=((tmp/d*x)%a2+a2)%(a2/d)*a1+r1; a1=a1/d*a2; } printf("%I64d\n",r1); } int main() { while(scanf("%I64d",&N)!=EOF) china(); return 0; }