藍橋杯 k倍區間

2021-09-12 20:22:59 字數 1435 閱讀 3724

題目描述

給定乙個長度為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) 

輸出 輸出乙個整數,代表ķ倍區間的數目。 

樣例輸入

樣例輸出

學習過這道題讓自己非常深刻地體會到了自己對字首和知識的欠缺,天真的以為暴力就能解決一切

下次做題時一定要對連續區間要敏感,字首和是一種多麼方便的方法啊!!

看過網上各位大佬的題解之後,也對這個字首和還有取模又有了一種新的理解

比如  [ l , r ] 上的區間判斷其對k取模是否為0,用sum陣列儲存字首和,即 [ l ,r ]上的區間和就等於sum [ r ] - sum [ l-1] 

而判斷sum [ r ] - sum [ l-1] 對k取模是否為0,就是判斷這兩個字首和對k取模是否相等

//  因為兩個數對k取餘後餘數相同,相減後 他們分別對k 取餘的餘數就減掉了

//   即(sum [ r ] - sum [ l-1] %k ==0 可以 推導出sum [ r ] %k==sum [ l-1 ]%k

而要實現上面說的這些步驟,就是對字首和取餘k

例如題目給的 1,2,3,4,5

取模2後的字首和分別是 1,1,0,0,1

其中 1 有三個 ,0 有兩個,對所有的1或所有的0中,根據組合數 c(3,2) 或c(2,2)求出其中的取模2後相同的字首和

**解釋:

//ans記錄的是 不從第乙個元素開始的區間的相同的個數,例如前面說的[2],[2,3,4,5],[3,4,5] (這些是取模2後為1的),[4](取模2後為0的)

//加上vis[0]是因為要記錄從從第乙個分別到第i個的區間中取模k 為 0的個數,例如([1,2,3],[1,2,3,4])

**如下

#includeint main()

; sum[1]=a[1]%k;

for(int i=2;i<=n;i++)

sum[i]=(sum[i-1]+a[i])%k;

long long vis[100007]=; // 該陣列是記錄有多少個相同的區間和

long long ans=0;

for(int i=1;i<=n;i++)

printf("%lld",ans+vis[0]);

//ans記錄的是 不從第乙個元素開始的區間的相同的個數

//加上vis[0]是因為要記錄從從第乙個分別到第i個的區間中取模k 為 0的個數

return 0;

}

藍橋杯 K倍區間

時間限制 2.0s 記憶體限制 256.0mb 給定乙個長度為n的數列,a1,a2,an,如果其中一段連續的子串行ai,ai 1,aj i j 之和是k的倍數,我們就稱這個區間 i,j 是k倍區間。你能求出數列中總共有多少個k倍區間嗎?輸入格式 第一行包含兩個整數n和k。1 n,k 100000 以...

藍橋杯 k倍區間

暴力模擬 雙迴圈肯定超時了,需要找到數字間的規律進行優化 includeusing namespace std typedef long long ll define maxn 100005 sum r sum l 1 就是區間 l,r 的和。區間 l,r 的和是k的倍數即 sum r sum l ...

藍橋杯 K倍區間

給定乙個長度為 n nn 的數列,a1,a2,an a 1,a 2,a n a1 a2 a n 如果其中一段連續的子串行 ai,ai 1 aj a i,a a j ai ai 1 aj 之和是 k kk 的倍數,我們就稱這個區間 i,j i,j i,j 是 k kk倍區間。你能求出數列中總共有多少個...