给n (2?≤?n?≤?100?000)个数,每次操作可以使相邻两数ai,aj变为分别ai-aj,ai+aj,求最少通过多少次操作,数列的最大公约数不为1
若d|(ai-aj)&&d|(ai+aj), 则d|[ai-aj)+(ai+aj)] && d|[(ai-aj)-(ai+aj)],即d|2ai&&d|2aj
故当前公约数为1时,每次操作要么公约数不变,要么使公约数变为2
题目转化为求初始公约数为1时,通过多少次操作使序列全为偶数
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #define INF 0x3f3f3f3f 6 #define MOD 1000000007 7 using namespace std; 8 typedef long long LL; 9 10 int N; 11 const int maxn = 1e5 + 10;; 12 int A[maxn]; 13 14 int gcd(int a, int b) { 15 return b == 0 ? a : gcd(b, a % b); 16 } 17 18 int main() { 19 int g = 0; 20 int ans = 0; 21 int cnt = 0; 22 scanf("%d", &N); 23 for (int i = 1; i <= N; i++) { 24 scanf("%d", &A[i]); 25 g = gcd(A[i], g); 26 if (A[i] & 1) { 27 cnt++; 28 } else { 29 ans += 2 * (cnt & 1) + (cnt / 2); 30 cnt = 0; 31 } 32 } 33 ans += 2 * (cnt & 1) + (cnt / 2); 34 if (g != 1) ans = 0; 35 puts("YES"); 36 printf("%d\n", ans); 37 return 0; 38 }