[英]C++ Number theory: Fastest way to compute max(y = a_i * x+ b_i) <= k
以下問題,當必須編寫快速代碼時:我有一個包含 2 個整數 a_i 和 b_i 的列表,我必須計算方程:y = (a_i * x + b_i),其中我只對 y 感興趣,而不對X。 所有 a_i 都是素數且彼此不同。 a_i = y / x,b_i = y % x。
y 有多種解,即使所有 a_i, b_i 對的 y 必須相同,因為 x 可以是任何整數。 因此我們有一個上限 k 並且 y <= k。 我想要盡可能高的 y(如果有解決方案)。 最大值(y)。
簡而言之:我想知道最大的整數 y(如果存在),y <= k 和給出的方程。 x >= 1。
我已經有一個理論上有效的“解決方案”,但這太慢了:
struct part {
unsigned int size, rest;
};
int solve(vector<part> &partions, int minK, int stepSize, int k) {
int sol = 0;
for (int i = k; i >= minK; i -= stepSize) {
bool works = true;
for (int j = 0; j < static_cast<int>(partions.size()); j++) {
if ((i - partions[j].rest) % partions[j].size != 0) {
works = false;
break;
}
}
if (works) return i;
}
return -1;
}
解釋:minK 是 max(a_i + b_i),因為我認為 y = a_i *1 + b_i 是一個方程的最小可能解,並且由於所有方程的 y 都相同,所以最大值是最好的下界。
stepSize 不是 1(為了使程序更快),而是 max(a_i),正如我所想的那樣,因為 max(a_i) 必須適合 y 並且 y = a_i * x + b_i,因此 x 是整數值,stepSize 是 a_i,而 max(a_i) 是最好的,因為這會減少循環運行的次數。
我現在使用 stepSize 嘗試從 k 到 minK 的所有 y,並測試所有對 a_i 和 b_i,如果它們滿足等式。 如果其中一個失敗,我必須繼續下去,直到找到解決方案或沒有解決方案 (-1)。
不幸的是,該算法太慢了(因為 a_i 和 b_i 可以達到 10^12),我想不出更多的優化。 我已經在互聯網上搜索了數論和算術,但找不到任何類似的東西。
你能幫我加快這段代碼的速度,或者提示我去一些處理這個問題的網站嗎?
您可以一次滿足一個 i,同時保留所有已經滿足的:step 是所有已經滿足的 a[i] 的 LCM(最初為 1)。 y 是滿足你已經做的所有那些的最小值。 關鍵概念是,滿足所有 i 的任何 Y 必須滿足您已經完成的所有Y=y+n*step
,因此它必須是Y=y+n*step
。 因此,對於每個 i,您可以直接計算y+n*step
mod a[i] 等於 b[i] 的最小 n(如果有)並設置y=y+n*step
和 step=lcm(step,a[一世])。 如果沒有這樣的 n 或者如果新的 y 大於 k,則中止。 一旦你完成了所有的 i,你就有了最小的 y,但你想要最大的 y 小於 k,這是一個微不足道的最終調整,因為它們相差很多步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.