關於K倍區間問題的神仙做法所記的筆記

2021-10-03 10:10:02 字數 1177 閱讀 3205

問題描述

給定乙個長度為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資料規模和約定

峰值記憶體消耗(含虛擬機器) < 256m

cpu消耗 < 2000ms

首先統計字首和sum[i] 表示a1+a2+…+ai.所以對於任意一段區間[l,r]的和就是sum[r]-sum[l-1].如果要保證這個區間和為k倍數就是:(sum[r]-sum[l-1])%k == 0.變形後就是:sum[r]%k==sum[l-1]%k,所以我們計算字首和的時候順帶模k,然後統計字首和中相同的資料就行了。複雜度o(n).注意資料可能會溢位。

我的筆記(關於處理資料的):

舉個例子,假設字首和中相同的資料只有一組,且個數為4個,那麼這4個相同的數a,b,c,d,就有6種不同的組合方式即6種不同的區間(3+2+1=6),而實際字首和陣列中顯然有多組不同的資料,我們要做的就是把每一組資料可能的組合方式求出來。最後,在求解過程中不可忽略的一點是,餘數等於0的情況,即該區間本身就是k的倍數;如,字首和陣列裡面有4個0,我們除了要計算這4個0的組合方式,還要計算0的個數,因為每個0所代表的,就是第i個數到第0個數之間的這個區間為k的倍數。

typedef

long

long ll;

ll a[

100100];

ll bk[

100100];

intmain()

a[0]=

0;for(

int i=

1;i<=n;i++

)int ans=0;

for(

int i=

1;i<=n;i++

) cout<;//0的組合方式已經在上面計算完畢了,現在要做的就是加上本身就是k的倍數的區間個數,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行每行包含乙個整數ai。1 ai ...

2017藍橋杯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 輸出乙...

第k大區間和問題的樹狀陣列實現

給定乙個整數序列a 1.n 定義sum i j a i a i l a j 將所有的sum i j 從小到大排序 其中i,j滿足1 i j n 得到乙個長為n n 1 2的序列,求該序列中的第k個元素。輸入格式 ktm.in 第一行有兩個整數n,k,其中0接下來n行每行乙個整數。順序給出序列a的元素...