題目1:k倍區間
給定乙個長度為 n 的數列,a1,a2,…an,如果其中一段連續的子串行 ai,ai+1,…aj 之和是 k 的倍數,我們就稱這個區間 [i,j] 是 k 倍區間。
你能求出數列中總共有多少個 k 倍區間嗎?
輸入格式
第一行包含兩個整數 n 和 k。
以下 n 行每行包含乙個整數 ai。
輸出格式
輸出乙個整數,代表 k 倍區間的數目。
資料範圍
1≤n,k≤100000,
1≤ai≤100000
輸入樣例:
5 2123
45輸出樣例:
6解題思路:
題目要求求所給區間的子區間和,可以暴力列舉所有子區間,然後利用字首和求區間和。枚舉子區間一般有兩種方式:列舉區間的兩端點,或者列舉區間的某端點和區間的長度。這兩種方式都需要兩重迴圈,時間複雜度為o(n2)根據題目所給資料範圍就超出了。可以在此基礎上對**進行優化。
其中兩重迴圈的**為
for
(int r =
1; r <= n; i++
)for
(int l =
1; l <= r; l++)if
((s[r]
- s[l-1]
)% k ==
0) res ++
;
可以發現,我們在內層迴圈中實際上找的是在0~r-1中有多少個s[i]與s[r]的餘數相同,這樣就又可以用桶進行優化。
優化後的**為:
#include
#include
using
namespace std;
const
int n =
100010
;typedef
long
long ll;
int n, k;
ll s[n]
;int cnt[n]
;int
main()
ll res =0;
for(
int i =
0; i <= n; i++
) cout << res << endl;
return0;
}
桶陣列的妙用
問題:給定乙個n個數的序列和乙個整數k,求在第乙個數到第i-1個中有多少個數與第i個數除以k的餘數相同。
利用桶陣列可以把時間複雜度降到o(n)
for
(int i =
0; i <= n; i++
)
題目2:遞增三元組
給定三個整數陣列
a=[a1,a2,…an],
b=[b1,b2,…bn],
c=[c1,c2,…cn],
請你統計有多少個三元組 (i,j,k) 滿足:
1≤i,j,k≤n
ai第二行包含 n 個整數 a1,a2,…an。
第三行包含 n 個整數 b1,b2,…bn。
第四行包含 n 個整數 c1,c2,…cn。
輸出格式
乙個整數表示答案。
資料範圍
1≤n≤105,
0≤ai,bi,ci≤105
輸入樣例:
31 1 1
2 2 2
3 3 3
輸出樣例:
27解題思路:
首先會想到暴力列舉,三重迴圈列舉所有情況,發現資料範圍太大會超時
想優化,根據資料範圍可以接受的時間複雜度為o(n)、o(nlogn)也就是只能列舉乙個陣列,由於a, b, c要求有序,所以列舉b陣列,然後對於列舉每乙個b看有多少個符合要求的a, c最終結果為a*c。
求乙個陣列中大於某個數的元素個數:字首和、sort+二分、雙指標
字首和做法:
用桶陣列記錄每個元素出現的次數,然後對求桶陣列的字首和s[i]就表示陣列中0~i的元素出現的次數。
#include
#include
#include
using
namespace std;
const
int n =
1e5+10;
int n;
int as[n]
, cs[n]
;int a[n]
, b[n]
, c[n]
;int
main()
long
long res =0;
for(
int i =
0; i < n; i++
)
cout << res << endl;
return0;
}
陣列 字首和 字首積及其應用
字首和 字首積也稱字首和陣列,字首積陣列。給一陣列a,字首和 新建一陣列b,陣列中每一項b i 儲存a中 0 i 的和 字尾和 新建一陣列b,陣列中每一項b i 儲存a中 i n 1 的和 字首積 新建一陣列b,陣列中每一項b i 儲存a中 0 i 的積 字尾積 新建一陣列b,陣列中每一項b i 儲...
字首和及簡單應用
通常,涉及連續子陣列問題的時候,我們使用字首和來解決。我們令 p i a 0 a 1 ldots a i 那麼每個連續子陣列的和 operatorname i,j 就可以寫成 p j p i 1 其中 0 i j 的形式。a 和為k的子陣列 給定乙個整數陣列和乙個整數 k,你需要找到該陣列中和為 k...
二維字首和應用
題目描述 aw最近比較佛系,開始玩起了種田遊戲養生。aw在種田的時候遇到了乙個問題,在一塊 n m 個方格的地圖上,他想圍一塊邊長為 k 的正方形土地當做西瓜田,但是每個方格的土地肥沃度 w 並不一樣,aw想圍出一塊肥沃度之和最大的土地,請你幫幫他。輸入乙個整數t,表示t組測試資料。對於每組測試資料...