思路
所求sum(A)为下标总和,f(0),f(1)f(2)...为下标值,所以问题就是如何求f(0),f(1),f(2)...然后相加。
通过分析样例一的解释可以得知,f(i)的值就是序列A中小于等于i的最大的那个数的下标,所以我们可以发现,序列中,f(0)和f(1)都是0,也就是对应序列中0的下标,f(2)到f(4),因为2,3,4都小于5,所以f(2),f(3),f(4)的值就是序列中2的下标。
就这里我们可以发现规律,(1)下标是从0开始递增,所以下标之和就是几个0加上几个1加上几个2这样子的形式,所以这里不难都得到f(i)的值;(2) 而这些下标分别有多少个取决于系列中相邻数的差值,也就是说相邻的两个序列之间f(i)的值相同,这样就能更快速的求出总和。
代码
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n,N;
n= sc.nextInt();
N= sc.nextInt();
int sum=0;
int cout = 1;//用来充当f(i)的值,这里直接从1开始,因为序列第一位为0是默认的,从序列第二位开始相加
int[] list = new int[2];
for (int i = 0; i < n; i++) {
if(i<1){
list[0] = sc.nextInt();
list[1] = list[0];
}else{
list[0] = list[1];
list[1] = sc.nextInt();
if(list[1]>N){//当输入的序列大于N时就没必要了,后面用不到
sum = sum+cout*(N-list[0]);
System.out.println(sum);
return;
}
sum = sum+cout*(list[1]-list[0]);//计算相同的f(i)之和并累加
cout++;
}
}
//这里是输入的数都小于N的情况
sum = sum+cout*(N-list[1]);
System.out.println(sum);
}
}