2021.01.26k倍区间
题目描述
给定一个长度为N的数列,A1, A2, … AN,如果其中一段连续的子序列Ai, Ai+1, … Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。
你能求出数列中总共有多少个K倍区间吗?
输入格式
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)
输出格式
输出一个整数,代表K倍区间的数目。
样例输入
5 2
1
2
3
4
5
样例输出
6
数据规模和约定
思路
考察知识:
- 前缀和
- 如果两个前缀和A(对应下标i),B(对应下标j),有A%k == B%k,则 [ i+1,j ] 中的元素一定是一个k倍区间。
注意:为了性能,在找k倍区间个数的时候,采取组合数学的式子num = n*(n-1)/2,即计算,而不是通过两个for循环进行遍历。
代码
class Solution {
int n,k;
void test() {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
k = cin.nextInt();
int[] a = new int[n+1];a[0] = 0;int s = 0;
int[] num = new int[k];
for(int i = 1; i <= n; i++) {
int t = cin.nextInt();
s+=t;
s= s%k;
a[i] = s;
}
for(int i = 0; i < n+1; i++) {
num[a[i]]++;
}
long cnt = 0;
for(int i = 0; i < k; i++) {
if(num[i] != 0) {
cnt+=(long)num[i]*(long)(num[i]-1)/2;
}
}
System.out.println(cnt);
}
}