藍橋杯 K倍區間

2021-10-22 17:18:15 字數 1794 閱讀 2814

給定乙個長度為 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倍區間。

你能求出數列中總共有多少個 k

kk 倍區間嗎?

輸入格式

第一行包含兩個整數 n

nn 和 kkk

以下 n

nn 行每行包含乙個整數 a

ia_i

ai​。

輸出格式

輸出乙個整數,代表 k

kk 倍區間的數目。

資料範圍

1 ≤n

,k

≤100000

1≤n,k≤100000

1≤n,k≤

1000

00,1≤a

i≤

100000

1≤a_i≤100000

1≤ai​≤

1000

00輸入樣例1:

5 212

345

輸出樣例1:
6
按照樸素的做法,我們需要列舉區間端點,這個的複雜度是o(n

2)

o(n^2)

o(n2

)。然後再用o(n

)o(n)

o(n)

的複雜度求出區間的總和,看看其是否是k

kk的倍數。此時必定超時。

可以看出,求區間總和我們可以利用字首和將複雜度降到o(1

)o(1)

o(1)

,那麼總的複雜度就會降到o(n

2)

o(n^2)

o(n2

),但是仍然會超時,所以我們需要想更優化的方案

我們在列舉左端點的時候,其實可以先列舉右端點,(s[r] - s[l - 1]) % k == 0,所以如果對於0 ~ r - 1,我們只需要知道s[l]與 s[r]模k同餘的個數,所以我們可以利用cnt陣列來記錄每乙個r % k的值,然後對於列舉每一r,結果加上cnt[s[r] % k]的個數即可

時間複雜度

o (n

)o(n)

o(n)

c++ **

#include

using namespace std;

typedef

long

long ll;

const

int n =

100010

;ll cnt[n]

, s[n]

;int n, k;

intmain()

ll res =0;

cnt[0]

++;// s[0] = 0,0 % k = 0;

for(

int r =

1;r <= n;r ++

)

cout << res << endl;

return0;

}

藍橋杯 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 10...

藍橋杯 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 ...