此題根據大佬的博文改寫,膜拜大佬!
題目
給定一個長度爲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倍區間的數目。
思路
邊讀入邊處理;
假如j之前(包括j)所有數的和爲sum[j];
由於K倍區間滿足(sum[j]-sum[i-1])%k=0;
變形得sum[j]%k =sum[i-1]%k;
即只需找在當前位置之前有多少和自己的sum%k相等;
每次循環都計算出sum%k,並尋找之前有多少個餘數相同的,累加起來,但這些還缺少一種情況,即sum%k = 0的情況,這種可以從0到此形成K倍區間;
由於對k取餘,餘數不會超過k,只需申請k個空間存儲;
這種算法的時間複雜度爲o(n);
代碼
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n,k,sum = 0;
long count = 0;
n = sc.nextInt();
k = sc.nextInt();
int[] cnt = new int[k];
for (int i = 0; i < n; i++) {
sum = (sum + sc.nextInt()) % k;
count += cnt[sum]++;
}
count += cnt[0];
System.out.println(count);
sc.close();
}
}