G. Greatest Common Divisor ###K //K
题目链接:https://codeforces.ml/gym/102823/problem/G
题意:每次操作使得整个区间+1 问最少多少次 使得整个区间的gcd大于1 如果不存在输出-1
思路:根据gcd的差分性质 转换成差分数组 即每次只能是a[1]++ 那么就是2~n的gcd d 要多少次才能变成大于1
设 d= 2~n 的gcd (差分后) 然后记得把d取绝对值(因为d可能为负数的gcd) 特判一下d==1 无解 d==0 的时候看 a[1]的值 为1就是1 否则为0
然后 枚举d的因子, 找 a[1] 至少加多少能达到因子的倍数 取一个min值即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 const int mod=1e9+7; 5 #define ll long long 6 #define ull unsigned long long 7 #define pi pair<int,ll> 8 #define fi first 9 #define sc second 10 #define pb push_back 11 int a[maxn]; 12 13 int gcd(int a,int b) 14 { 15 if(b==0) return a; 16 return gcd(b,a%b); 17 } 18 19 20 int main() 21 { 22 ios::sync_with_stdio(0); 23 cin.tie(0); 24 int t; 25 cin>>t; 26 int c=0; 27 while(t--) 28 { 29 int n; 30 cin>>n; 31 for(int i=1;i<=n;i++) cin>>a[i]; 32 for(int i=n;i>=1;i--) a[i]-=a[i-1]; 33 int x=0; 34 for(int i=2;i<=n;i++) x=gcd(x,a[i]); 35 x=abs(x); 36 int ans=1e9; 37 if(x==0) 38 { 39 if(a[1]==1) ans=1; 40 else ans=0; 41 cout<<"Case "<<++c<<": "<<ans<<'\n'; 42 continue; 43 } 44 if(x==1) 45 { 46 ans=-1; 47 cout<<"Case "<<++c<<": "<<ans<<'\n'; 48 continue; 49 } 50 for(int i=1;i*i<=x;i++) 51 { 52 if(x%i!=0) continue; 53 int q=i; 54 if(q!=1) 55 { 56 ans=min(ans,(q-a[1]%q)%q); 57 } 58 q=x/i; 59 ans=min(ans,(q-a[1]%q)%q); 60 } 61 cout<<"Case "<<++c<<": "<<ans<<'\n'; 62 63 64 65 66 67 } 68 69 70 71 }

浙公网安备 33010602011771号