?
GCD模板
__int64 gcd(__int64 a,__int64 b) {return b==0? a:gcd(b,a%b); }
?歐幾里德算法又稱輾轉相除法,用于計算兩個整數a,b的最大公約數。其計算原理依賴于下面的定理:
gcd函數就是用來求(a,b)的最大公約數的。
gcd函數的基本性質:
gcd(a,b)=gcd(b,a)=gcd(-a,b)=gcd(|a|,|b|)
證明:
基本算法:設a=qb+r,其中a,b,q,r都是整數,則gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b)。
第一種證明:
? ? ? a可以表示成a = kb + r,則r = a mod b
假設d是a,b的一個公約數,則有
d|a, d|b,而r = a - kb,因此d|r
因此d是(b,a mod b)的公約數
假設d 是(b,a mod b)的公約數,則
d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公約數
因此(a,b)和(b,a mod b)的公約數是一樣的,其最大公約數也必然相等,得證。
第二種證法:
第二種證明:
? ??要證歐幾里德算法成立,即證: gcd(a,b)=gcd(b,r),其中 gcd是取最大公約數的意思,r=a mod b
??? 下面證 gcd(a,b)=gcd(b,r)
??? 設? c是a,b的最大公約數,即c=gcd(a,b),則有 a=mc,b=nc,其中m,n為正整數,且m,n互為質數
??? 由 r= a mod b可知,r= a- qb 其中,q是正整數,
??? 則 r=a-qb=mc-qnc=(m-qn)c
??? b=nc,r=(m-qn)c,且n,(m-qn)互質(假設n,m-qn不互質,則n=xd, m-qn=yd 其中x,y,d都是正整數,且d>1
??????????????????????????????????????????????????????????????? 則a=mc=(qx+y)dc, b=xdc,這時a,b 的最大公約數變成dc,與前提矛盾,
???????????????????????????????????????????????????????????????? 所以n ,m-qn一定互質)
??? 則gcd(b,r)=c=gcd(a,b)
??? 得證。
?
擴展歐幾里德定理
對于不完全為 0 的非負整數 a,b,gcd(a,b)表示 a,b 的最大公約數,必然存在整
數對 x,y ,使得 gcd(a,b)=ax+by。
證明:
基本算法:對于不完全為 0 的非負整數 a,b,gcd(a,b)表示 a,b 的最大公約數,必然存在整數對 x,y ,使得 gcd(a,b)=ax+by。
證明:設 a>b。
1,顯然當 b=0,gcd(a,b)=a。此時 x=1,y=0;
2,ab!=0 時
設 ax1+by1=gcd(a,b);
bx2+(a mod b)y2=gcd(b,a mod b);
根據樸素的歐幾里德原理有 gcd(a,b)=gcd(b,a mod b);
則:ax1+by1=bx2+(a mod b)y2;
即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;
根據恒等定理得:x1=y2; y1=x2-(a/b)*y2;
? ? ?這樣我們就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
?上面的思想是以遞歸定義的,因為 gcd 不斷的遞歸求解一定會有個時候 b=0,所以遞歸可以結束。
以上來自 這篇博客 具體應用可以繼續看這篇文章
模板
int exgcd(int a,int b,int &x,int &y) {if(b == 0){x = 1; y = 0; return a;}int d = exgcd(b, a % b,x,y);int temp = x;x = y;y = temp - a / b * y;return d; }
?快速冪取模
http://blog.csdn.net/hkdgjqr/article/details/5381292
快速冪取模就是在O(logn)內求出a^n mod b的值。算法的原理是ab mod c=(a mod c)(b mod c)mod c
二分遞歸
long exp_mod(long a,long n,long b) {long t;if(n==0) return 1%b;if(n==1) return a%b;t=exp_mod(a,n/2,b);t=t*t%b;if((n&1)==1) t=t*a%b;return t; }
基于二進制
LL q_mod(LL a,LL b)
{
LL d,t;
d = 1,t=a;
while(b)
{
if(b&1) d = (d*t)%mod;
b/=2;
t = (t*t)%mod;
}
return d;
}
?http://acm.hdu.edu.cn/showproblem.php?pid=2817


1 #include<stdio.h> 2 #define N 200907 3 __int64 exp_mod(__int64 a,__int64 b) 4 { 5 __int64 d,t; 6 d = 1; 7 t = a; 8 while(b>0) 9 { 10 if(b%2==1) 11 d = d*t%N; 12 b=b/2; 13 t = t*t%N; 14 } 15 return d; 16 } 17 int main() 18 { 19 __int64 n,m,a1,a2,a3,d,s,x; 20 int i,j,k,t; 21 scanf("%d", &t); 22 while(t--) 23 { 24 scanf("%I64d%I64d%I64d%d",&a1,&a2,&a3,&k); 25 if(a2-a1==a3-a2) 26 { 27 d = a3-a2; 28 s = (a1%N+d*(k-1)%N)%N; 29 printf("%I64d\n",s); 30 } 31 else 32 { 33 x = a3/a2; 34 printf("%I64d\n",(a1*exp_mod(x,k-1))%N); 35 } 36 } 37 return 0; 38 }
?
?