标签:gcdr gcd 数轴 int 最小 A1633 公倍数 区间 计蒜客
考察:GCD+前缀和思想
根据题意,最多允许一个区间和其他区间的距离不一样.因此在计算的时候我们需要去掉那个区间.那么剩下的区间取多大呢?可以发现:剩下区间要求的长度一定为它们的最小公倍数.这样才能凑得相等.假设剩下区间要求长度为k,区间需要增加的点数为len/k-1.因此最小的点数就是k尽量大
接下来是几个要解决的问题
1.如何在时间范围内求出剩下的最小公倍数
答: 我们可以利用前缀和思想.gcdl[i]存储1~i的区间的最小公倍数,gcdr[i]存储i~n的最小公倍数,去掉某个区间的剩下的公倍数就是由两个再次求gcd.
2.如何计算答案?
答:求出去掉每个区间的最小公倍数后,我们尽量取最大值,会有两种情况:
- 去掉的区间不能整除最大值.因此计算的时候不能算入其中
- 去掉的区间也能整除最大值.因此答案要去掉的区间是增加点数最多的区间
以上即可求出答案
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 typedef long long ll; 5 const int N = 1e5+10; 6 int n,b[N],a[N],gcdl[N],gcdr[N],ans[N]; 7 int gcd(int a,int b) 8 { 9 return b?gcd(b,a%b):a; 10 } 11 int main() 12 { 13 int maxn = -1,idx = -1,len = -1; ll res = 0; 14 scanf("%d",&n); 15 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 16 sort(a+1,a+n+1); 17 for(int i=1;i<=n;i++) b[i] = a[i]-a[i-1]; 18 gcdl[2] = b[2],gcdr[n-1] = b[n]; 19 for(int i=3;i<=n;i++) gcdl[i] = gcd(gcdl[i-1],b[i]); 20 for(int i=n-2;i>0;i--) gcdr[i] = gcd(gcdr[i+1],b[i+1]); 21 ans[1] = gcdr[2]; ans[n-1] = gcdl[n-1]; 22 for(int i=2;i<=n-2;i++) ans[i] = gcd(gcdl[i],gcdr[i+1]); 23 for(int i=1;i<=n-1;i++) maxn = max(maxn,ans[i]); 24 for(int i=2;i<=n;i++) 25 { 26 if(b[i]%maxn!=0) { idx = i;continue; } 27 res+=(ll)b[i]/maxn-1; 28 len = max(b[i],len); 29 } 30 if(idx==-1) res-=len/maxn-1; 31 printf("%lld\n",res); 32 return 0; 33 }
标签:gcdr,gcd,数轴,int,最小,A1633,公倍数,区间,计蒜客 来源: https://www.cnblogs.com/newblg/p/14290563.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。