题目:
解析:
要求的是公差d范围为[1,n]首相为d,长度为n的序列bi中其对应位置的bi[i]能被输入的n个数所形成的序列a,对应位置的a[i]所整除的数的个数总和.
上图:
标蓝的数字是符合题目要求的,共14个,由图可知,等差序列列出组成表格后,其每列也是等差序列,其公差d为b1[i](第一个等差序列对应的那一项),我们把关注点放到每一列上,相信你也发现了,我们只要求a序列的每一项能整除表格每一列的个数相加即可;
定义要求总数sum=0
当b1[i]能被a[i]整除时(b1[i]%a[i]==0),则这一列每一个数都能被a[i]整除,即是sum+=n
而不能时,这一列能被a[i]整除的就只有a[i]和b1[i]的最小公倍数为首相,公差为a[i]和b1[i]的最小公倍数的序列中的数能被整除,设这个序列为C,最小公倍数(公差)为C(d).
举个例子:
在列题的基础上加了第5个数——4,其那一列只有20能被整除
4与5的最小公倍数为20,其‘4’只能整除20,40,60...,因为这一列是以5为公差的等差数列,所以只有在n够大时出现20,40,60,80..,这些数中含才有‘4’这个因子
所以我们只需要加上b1[i]到n*b1[i](b5[i])中有多少个序列C中的数,即n*b1[i]/C(d)
所以另外一种情况:sum+=n*b1[i]/C(d)
求两个数最小公倍数方法,设两个数为A,B
先求出最大公约数X,再用A或B随便一个数除X,这样得的数就不含其因子,然后再乘另外一个数则可得最小公倍数.
详细介绍:
最后代码:
import java.util.*;
import java.math.*;
public class MainF序列 {
public static void main(String[] args) {
Scanner Lps=new Scanner (System.in);
long n=Lps.nextInt();
long sum=0;
long n1[]=new long [(int)n];
for (int i = 0; i < n1.length; i++) {
n1[i]=Lps.nextLong();
}
for (long i = 0; i <n; i++) {
if((i+1)%n1[(int)i]==0) sum+=n;//因为数组下标从0,开始所以实际第i项要加1
else {
long x=((i+1)/gcd(i+1,n1[(int)i]) )*n1[(int)i];
sum+=n*(i+1)/x;
}
}
System.out.print(sum);
}
public static long gcd(long a,long b) {
while(b!=0) {
long x=b;
b=a%b;
a=x;
}
return a;
}
}