問題描述
給定乙個長度為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倍區間的數目。
樣例輸入52
1234
5樣例輸出
6
求區間[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
此時sum:[ 1 , 0 , 0 , 1 , 1 , 0 ]就是輸入的數%k得到的。
正確的區間 [ l , r ] 就是:sum[ l ] = sum [ r ]
如果有3個相同,則:有 1+2 個區間(就像是3個人中找兩個人手牽手,有多少中找法,就是c2
3 = 3*2/2)。
如果有n個相同,則:有 1+2+···+(n-1)。(c2
n = n(n-1)/2 )
注意:因為區間長度也可以是1,所以餘數為0的數,自己也是符合的。(相當於輸入的數本身就是k的倍數)
**如下:
#include
using
namespace std;
typedef
long
long ll;
const
int n =
100010
;int n,k;
int num[n]=;
//原始陣列
int sum[n]=;
//字首和%k 的陣列
int res[n]=;
//餘數為i出現的次數
ll ans;
//答案
intmain()
cout << ans + res[0]
;//加上餘數是0的個數,因為自己乙個也是屬於乙個區間
return0;
}
K倍區間 字首和
第二天叫醒我的不是鬧鐘,是夢想!題目描述 給定乙個長度為n的數列,a1,a2,an,如果其中一段連續的子串行ai,ai 1,aj i j 之和是k的倍數,我們就稱這個區間 i,j 是k倍區間。你能求出數列中總共有多少個k倍區間嗎?輸入 第一行包含兩個整數n和k。1 n,k 100000 以下n行每行...
k倍區間(字首和)
題目如下 解題思路 這個思路實在太強了 1.sum i 代表a 0 a i 1 的和,那麼sum r sum l 1 即為區間 l,r 之間的和,即求 sum r sum l 1 k 0,即求sum r k sum l 1 k 即先求出字首和。在求出字首和的同時 k。2.有的人可能對 的最後一段不太...
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 100000 輸出乙...