給定乙個長度為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 21
2 3
4 5
程式應該輸出:
6資源約定:
峰值記憶體消耗(含虛擬機器) < 256m
cpu消耗 < 2000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:「請您輸入...」 的多餘內容。
注意:main函式需要返回0;
只使用ansi c/ansi c++ 標準;
不要呼叫依賴於編譯環境或作業系統的特殊函式。
所有依賴的函式必須明確地在原始檔中 #include
不能通過工程設定而省略常用標頭檔案。
提交程式時,注意選擇所期望的語言型別和編譯器型別。
思路:
1,暴力字首和:列舉i和j(j大於等於i),從1到n,從前往後算區間和等於k的個數(但是兩個for迴圈,在n等於100000時,o(n^2)會超時)【維護乙個區間:字首和(靜態資料)、樹狀陣列、區間數,因為陣列位靜態陣列,所以選擇字首和;
2,優化字首和:求區間和%k的餘數(s[i]),利用同餘做差是模的倍數,然後就可以統計不同s[i]的個數cnt[s[i]],然後從相同的cnt[s[i]]選擇任意兩個就可以組成乙個k倍區間。
理解:題目中的
5 21 2
3 4 5
中有6個區間,就是【1,2,3】【1,2,3,4】【2,3,4,5】【3,4,5】
序號 0 1 2 3 4 5
a 1 2 3 4 5
s 0 1 3 6 10 15
s' 0 1 1 0 0 1
其中:s[i ] = 求和0~i的ai的和
si[i] = s[i] % k
因為:區間和%k餘數為1的有:(3個選2,即c3 2)
s'2-s'1-----
s'5 - s『1 ------【2,3,4,5】
s『5 - s『2------【3,4,5】
區間和%k餘數為0的有:(3個選2個,即c3 2)
s『3 - s'0:-----【1,2,3】
s『4 - s』0:----【1,2,3,4】
s『4 - s』3:-----
參考**1(暴力):
#include const int maxn = 100005;
int a[maxn];
int s[maxn];//字首和
int main()
long long ans = 0;
for (int i = 1; i <= n; ++i) }}
printf("%lld", ans);
return 0;
}
#include #include using namespace std;
const int maxn = 100005;
int a[maxn];
int s[maxn];//字首和
mapcnt;//同餘的個數統計
int main()
long long ans = 0;
for (int j = 0; j < k; ++j)
printf("%lld", ans);
return 0;
}
第八屆藍橋杯省賽C B組 K倍區間
給定乙個長度為 n 的數列,a1,a2,an,如果其中一段連續的子串行 ai,ai 1,aj 之和是 k 的倍數,我們就稱這個區間 i,j 是 k 倍區間。你能求出數列中總共有多少個 k 倍區間嗎?輸入格式 第一行包含兩個整數 n 和 k。以下 n 行每行包含乙個整數 ai。輸出格式 輸出乙個整數,...
第八屆藍橋杯省賽C B組 K倍區間
演算法標籤 字首和 題目描述 給定乙個長度為 n 的數列,a1,a2,an,如果其中一段連續的子串行 ai,ai 1,aj 之和是 k 的倍數,我們就稱這個區間 i,j 是 k 倍區間。你能求出數列中總共有多少個 k 倍區間嗎?輸入格式 第一行包含兩個整數 n 和 k。以下 n 行每行包含乙個整數 ...
K倍區間 第八屆藍橋杯省賽C B組
題目描述 給定乙個長度為 n 的數列,a1,a2,an,如果其中一段連續的子串行 ai,ai 1,aj 之和是 k 的倍數,我們就稱這個區間 i,j 是 k 倍區間。你能求出數列中總共有多少個 k 倍區間嗎?輸入格式 第一行包含兩個整數 n 和 k。以下 n 行每行包含乙個整數 ai。輸出格式 輸出...