CFR 798 C. Mike and gcd problem ( Math )
題意:
給長度為 N 的數列 A。每次可以進行的操作為,選擇一個 i,並執行 A[ i ], A[ i + 1 ] = A[ i ] - A[ i + 1 ], A[ i ] + A[ i + 1 ]。問至少要進行幾次操作,才能使得 gcd( A ) > 1。
制約:
The first line contains a single integer n (2 ≤ n ≤ 100 000) — length of sequence A.
The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 1e9) — elements of sequence A.
解法:
若原始的 gcd( A ) > 1,直接輸出 0。
注意到對於 ( a, b ):
一次操作:( a - b, a + b )
二次操作:( -2 * b, 2 * a )
三次操作:( -2 * ( a + b ), 2 * ( a - b ) )
四次操作:( -4 * a, -4 * b )
....
觀察到 gcd( a - b, a + b ) = 2 * gcd( a, b )
證明:
d = gcd( a - b, a + b )
d | a - b and d | a + b
=> d | ( a - b ) + ( a + b ) and d | ( a - b ) - ( a + b )
=> d | gcd( 2 * a, 2 * b )
所以只在意數列的奇偶性,依序獨立處理即可。
時間 / 空間複雜度:
O( N lg max_A )
from functools import reduce N = int( input() ) A = list( map( int, input().split() ) ) def gcd( a,b ): if b == 0: return a return gcd( b, a % b ) print( "YES" ) if reduce( gcd, A ) > 1: print( 0 ) else: ans = 0 for i in range( N - 1 ): while A[ i ] & 1: ans += 1 A[ i ], A[ i + 1 ] = A[ i ] - A[ i + 1 ], A[ i ] + A[ i + 1 ] if A[ N - 1 ] & 1: ans += 2 print( ans )