藍橋杯歷年真題 k倍區間

2021-08-17 19:07:31 字數 1192 閱讀 4541

給定乙個長度為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樣例輸出

6這道題難度中等,主要考察我們的數學以及演算法的優化能力。從表面上看,我們可以使用巢狀迴圈暴力求解,時間複雜度為o(n的平方),但是,題目中明確指出,oj提供的測試資料數量高達100000個,由此看出,暴力求解明顯會超出時間要求,所以,我們需要探索一下一種更為簡便的求法。

我們先來舉乙個簡單的例子:在陣列區間[i,j]中,我們可以設i<=k<=j,設陣列前k個元素的和為sum[k],前j個元素的和和為sum[j],這是,假設如果sum[k]%k == sum[j]%k的時候,我們可以發現,(sum[j] - sum[k])% k ==0 ,由此我們可以看出,在區間[k , j]中的元素之和是k的倍數,所以我們可以利用這個特點來統計在陣列[i , j]中,有相同餘數的子串行之和的個數,即num[sum[k]%k],便可進行進一步的統計操作,舉乙個簡單的例子

數列 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#include#include#includeusing namespace std;

long long sum[100000];

int num[100000];

int main()

cout<

k倍區間 藍橋真題

列舉所有區間是o n 2 這是為了遍歷所有區間 但是這個過程我們做了很多無用功 只需要遍歷一遍 這是為了遍歷每個k倍區間的右端點 而左端點可以通過之前的一些結果得出 遍歷過程中 對於每個i 都有book sum i k 這樣就知道從 1 到 i 1 有多少個區間和餘數和 1,i 相同的區間 兩者相減...

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