多多路上从左到右有N棵树(编号1~N),其中第i个颗树有和谐值Ai。
多多鸡认为,如果一段连续的树,它们的和谐值之和可以被M整除,那么这个区间整体看起来就是和谐的。
现在多多鸡想请你帮忙计算一下,满足和谐条件的区间的数量。
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int M = scanner.nextInt();
int[] A = new int[N];
for(int i = 0; i < N; i++){
A[i] = scanner.nextInt();
}
int count = 0;
int sum = 0;
Map<Integer, Integer> record = new HashMap<>();
//遍历数组nums之前,record提前放入 0:1 键值对,代表求第 0 项前缀和之前,前缀和 mod K 等于 0 这种情况出现了 1 次。
record.put(0,1);
for(int elem : A){
sum+=elem;//前缀和
int model = (sum % M + M) % M;//取余数
//getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值0。
record.put(model, record.getOrDefault(model, 0)+1);
}
//values() 方法返回映射中所有 value 组成的 Set 视图
for(int n : record.values()){
count+=n*(n-1)/2;
}
//for(Map.Entry<Integer, Integer> entry : record.entrySet()){
// count+=entry.getValue()*(entry.getValue()-1)/2;
//}
System.out.println(count);
}
对于这个计算的方式
计算前n个数进行求和然后取余 计入Map
for(int elem : A){
sum+=elem;//前缀和
int model = (sum % M + M) % M;//取余数
//getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值0。
record.put(model, record.getOrDefault(model, 0)+1);
}
举个栗子:
输入5个数 M为3 也就是求这5颗数的和谐值对3能不能整除 求出能整除的组合
我输入 3 4 5 6 7 然后M输入3
分析:第一棵树和谐值为3 第二棵树和谐值为3+4=7 依次为:12,、18、25
计算:
每棵树对3求余数
树 | 余数 |
---|---|
树0(代表0项 余数为0已经出现了一次) | 0 |
树1 | 0 |
树2 | 1 |
树3 | 0 |
树4 | 0 |
树5 | 1 |
由我们上图自己计算的结果:
相同余数的前缀区间任选两个所构成的中间区间一定和谐(因为大的那个前缀区间求和减去小的前缀区间求和,刚好把那个多出来的余数减掉了,因此中间区间求和一定能被m整除)
所以:
共有7个区间
运行验证是正确的