問題描述思路:給定乙個長度為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 2123
45樣例輸出
資料規模和約定
峰值記憶體消耗(含虛擬機器) < 256m
cpu消耗 < 2000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:「請您輸入...」 的多餘內容。
注意:main函式需要返回0;
只使用ansi c/ansi c++ 標準;
不要呼叫依賴於編譯環境或作業系統的特殊函式。
所有依賴的函式必須明確地在原始檔中 #include
不能通過工程設定而省略常用標頭檔案。
提交程式時,注意選擇所期望的語言型別和編譯器型別。
通過字首和的方式,計算sum【i】mod k 的值,i++,等到下乙個相等時,ans+=cnt【sum【i】 】。
求區間[l,r]的和是k的倍數的個數。求區間和,我們可以通過字首和來求出。我們規定sum[i]表示第1個元素到第i個元素的和。那麼sum[r] - sum[l-1]就是區間[l,r]的和。區間[l,r]的和是k的倍數即(sum[r] - sum[l-1])%k == 0 即sum[r]%k == sum[l-1]%k
那麼,我們求出每個字首和,在求的過程中取模,兩個相等的字首和就能組成乙個k倍區間。我們可以在計算完字首和以後,使用兩層for迴圈來計數k倍區間的個數。但是由於資料量較大,這樣是會超時的。那麼我們是否能在計算字首和的過程中來記錄k倍區間的個數呢?
我們用乙個陣列cnt[i]表示當前位置之前,字首和取模後等於i的個數。舉個例子:
數列 1 2 3 4 5 mod = 2
對前1個數的和取模, 為1 之前有0個字首和取模後為1,個數+0
對前2個數的和取模, 為1 之前有1個字首和取模後為1,個數+1
對前3個數的和取模, 為0 之前有0個字首和取模後為0, 個數+0
對前4個數的和取模, 為0 之前有1個字首和取模後為0,個數+1
對錢5個數的和取模, 為1 之前有2個字首和取模後為1,個數+2
到目前為止ans = 4。但是ans應該等於6,因為這樣計算後,我們漏掉了前i個數的和取模是k的倍數的情況,即[0,i]區間和是k的倍數,因此,我們要在ans = 4 的基礎上 加上字首和取模後為0的個數 即ans+2 = 6;
**如下:
題目思路來自以下部落格:#include using namespace std;
#define m 100005
int sum[m];
int cnt[m];
long long int ans;
int main()
printf("%lld\n",ans+cnt[0]);
return 0;
}
歷屆試題 k倍區間
問題描述 給定乙個長度為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 ...
歷屆試題 k倍區間
問題描述 給定乙個長度為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 ...
歷屆試題 k倍區間
題目 問題描述 給定乙個長度為n的數列,a1,a2,an,如果其中一段連續的子串行ai,ai 1,aj i j 之和是k的倍數,我們就稱這個區間 i,j 是k倍區間。你能求出數列中總共有多少個k倍區間嗎?輸入格式 第一行包含兩個整數n和k。1 n,k 100000 以下n行每行包含乙個整數ai。1 ...