問題 E 求方案

2022-04-08 14:55:25 字數 1371 閱讀 8361

題目描述

有n個正整數排成一行。你的目的是要從中取出乙個或連續的若干個數,使它們的和能夠被k整除。

例如,有6個正整數,它們依次為1,2,6,3,7,4。若k=3,則你可以取出1,2,6,或者2,6,3,7,也可以僅僅取出乙個6或者3使你所取的數之和能被3整除。當然,滿足要求的取法不止以上這4種。事實上,一共有7種取法滿足要求。

給定n和k,以及這n個數。你的任務就是確定從這n個數中取出其中乙個數或者若干連續的數,使它們的和能被k整除有多少方法。記ha=1234567,由於取法可能很多,因此你只需要輸出它mod ha的值即可

輸入第一行為兩個整數n,k。以下n行每行乙個正整數,描述這個序列。

輸出輸出乙個整數,為答案mod ha的結果。

樣例輸入

複製樣例資料

6 3126

374樣例輸出

7首先要求一段和是k的倍數, 那麼首先想到的肯定是利用字首和sum[i] ,求字首和, 然後區間和就是sum[j] - sum[i - 1]. j , i ∈(1 , n) , 那麼只要(sum[j] - sum[i - 1]) % k == 0 , 那麼這個就是乙個成功的方案, 那麼這個公式又表示什麼呢, 兩個字首和相減是k的倍數,不就是這兩個字首和同餘嘛, 可以簡單的化簡一下,就出來了, 令sum[j] = ka + t1 , sum[i - 1] = kb + t2 , 那麼為了滿足這個公式就是k(a - b) + t1 - t2 是k的倍數, 此時此刻t1 + t2 == 0 , 即兩個字首和同餘,

由此我們可以隨便用兩個sum % k 相等的數構成乙個區間和,並且這個區間和肯定滿足題目給的條件,那麼我們就存一下sum % k 有多少個相同 , num[sum % k] ++ ,然後我們就可以列舉餘數, 用該餘數所代表的字首和構成乙個個區間和,

這個題也就轉化為了, 從乙個餘數相同的集合裡面拿出兩個數來,相減構成乙個新的數,有多少方案 , 第一有num[i] 個方案 , 第二次有num[i - 1] 個方案, 但是有重複的,所以就是num[i] * (num[i ] - 1) / 2, 注意,num表示的是字首和%k的餘數, 我們用兩個這種數來構造,是構造乙個區間和滿足題目要求, 但是這個區間和要是就是乙個字首和, 我們之前在乙個集合裡拿出兩個元素的方法就不適用了, 因為那個是兩個數相減, 要是只是字首和%k == 0 了, 也就是字首和就滿足要求了,此時此刻,就是ans + num[0] 了

#include 

using namespace std;

const

int n =

5e5+10;

typedef long

long ll ;

ll a[n]

;int

main()

揹包問題求方案數 揹包問題求具體方案

在01揹包的基礎上要求出最優解的方案數 具體的方案 揹包問題求方案數 題目鏈結 解題思路 我們可以設定乙個與陣列f功能類似的陣列g,其中f i 儲存的是體積等於i的最優解 這裡是等於,之前的部落格說的是小於等於,原因後面會說 而g i 儲存的是體積等於i時的最優解的方案數,而f i 為什麼儲存的是等...

揹包問題求方案數

有 n件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i 件物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最優選法的方案數。注意答案可能很大,請輸出答案模 1e9 7 的結果。第一行兩個整數,n,v,用空格隔開,分別表示物品...

揹包問題求方案數

第二天叫醒我的不是鬧鐘,是夢想!有 n 件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i 件物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出 最優選法的方案數。注意答案可能很大,請輸出答案模 109 7 的結果。輸入格式 第...