評審選擇了一個區間 $[1, n]$ 中的整數 $x$。你的任務是猜出這個數字。為了避免盲目猜測,你可以進行詢問。在每次詢問中,你可以提供一個區間 $[0, c]$ 中的整數 $y$,我們將回答你 $x + y$ 的因數個數。
為了增加難度,在單次程式執行過程中,你必須解決 $t$ 個測試案例。你總共可以進行的詢問次數限制為 $q$。
互動
這是一個互動式問題。你必須編寫一個程式,透過提供的函式庫與評審進行通訊。若要使用該函式庫,請在你的程式中加入:
- C++:
#include "dzilib.h" - Python:
from dzilib import GetT, GetN, GetQ, GetC, Ask, Answer
函式庫提供以下函式:
GetT()– 回傳參數 $t$ —— 需要解決的測試案例數量。GetN()– 回傳參數 $n$ —— 隱藏數值 $x$ 的上限。GetQ()– 回傳參數 $q$ —— 所有 $t$ 個測試案例中,你總共可以進行的詢問次數上限。GetC()– 回傳參數 $c$ —— 你可以提供的數值 $y$ 的上限。Ask(y)– 回傳隱藏數值 $x$ 加上 $y$ 後的正因數個數。必須滿足 $0 \le y \le c$。Answer(z)– 通知函式庫你認為隱藏數值 $x$ 為 $z$。此函式不回傳任何值(在 C++ 中為void型別)。
在 Python 中,所有函式庫參數及回傳值皆為整數型別。在 C++ 中,函式所接收及回傳的型別與提供的範例函式庫一致,詳情請參閱「實作細節」章節。
在程式執行的任何時刻(除了結束時),只有一個測試案例是活躍的。第一個測試案例在程式開始執行時立即啟動。當測試案例活躍時,你可以使用 Ask 函式進行詢問。當你確定隱藏數值 $x$ 時,可以使用 Answer 函式提交,函式庫將進行驗證。如果提交的數值不正確,函式庫將終止程式並給予「錯誤答案 (wrong answer)」的判決。如果數值正確,函式將結束;如果該測試案例不是最後一個,則會立即啟動下一個測試案例。在回答完最後一個測試案例後,你應該結束程式。如果你沒有這樣做並嘗試再次呼叫 Ask 或 Answer,你將收到「錯誤答案」的判決。
你可以隨時呼叫 GetT、GetN、GetQ 及 GetC,且它們的回傳值不會改變。這些函式不計入詢問次數限制,但會消耗處理器時間。參數 $q$ 僅限制 Ask 函式的呼叫次數。當你超過總允許的詢問次數時,函式庫將終止程式並給予「錯誤答案」的判決。
請勿從標準輸入讀取任何資料,也不要向標準輸出寫入任何內容。禁止任何試圖影響評測函式庫內部運作的行為。
實作細節
所有測試中的隱藏數值 $x$ 及其順序皆已預先確定。這意味著與你程式通訊的函式庫不會是惡意的,也不會根據你程式的行為調整其反應。
題目中給出的限制僅針對你的程式所消耗的時間與記憶體。然而,函式庫的執行時間與記憶體消耗可能取決於測試案例以及你程式的具體行為。因此,SIO2 上的時間與記憶體限制會比題目中給出的略大。
範例
在範例測試中,$t = 2, n = 10^6, q = 10^4, c = 10^{15}$,隱藏數值依序為 $1000$ 與 $1$,與函式庫的互動範例如下:
| 呼叫函式 | 結果 | 說明 |
|---|---|---|
GetT() |
$2$ | $t = 2$。 |
GetN() |
$1\,000\,000$ | $n = 10^6$。 |
GetQ() |
$10\,000$ | $q = 10^4$。 |
GetC() |
$1\,000\,000\,000\,000\,000$ | $c = 10^{15}$。 |
Ask(1) |
$8$ | $x + 1$ 有 $8$ 個因數:$1, 7, 11, 13, 77, 91, 143$ 與 $1001$。 |
Ask(24) |
$11$ | $x + 24$ 有 $11$ 個因數:$1, 2, 4, 8, 16, 32, 64, 128, 256, 512$ 與 $1024$。 |
Answer(1000) |
– | 正確答案,啟動下一個測試案例。 |
GetT() |
$2$ | 允許的詢問 – 回傳值不變。 |
Answer(1) |
– | 正確的互動範例並提交最後一個測試案例的正確答案。回答後應結束程式。 |
共進行了 $2$ 次 Ask 詢問,符合 $10\,000$ 次詢問的限制。請記住,詢問次數限制是針對單次測試中所有測試案例的總和。
子任務
在同一測試群組中,所有測試案例皆具有相同的 $t, n, q$ 與 $c$ 值,如下表所示:
| 群組編號 | $t$ | $n$ | $q$ | $c$ |
|---|---|---|---|---|
| $1$ | $50$ | $10^5$ | $50\,000$ | $10^{12}$ |
| $2$ | $50$ | $10^6$ | $5\,000$ | $10^{12}$ |
| $3$ | $10$ | $10^9$ | $50\,000$ | $10^{12}$ |
| $4$ | $10$ | $10^{14}$ | $5\,000$ | $10^{17}$ |
| $5$ | $10$ | $10^{14}$ | $2\,000$ | $10^{17}$ |
| $6$ | $10$ | $10^{14}$ | $1\,300$ | $10^{17}$ |
| $7$ | $10$ | $10^{14}$ | $950$ | $10^{17}$ |
| $8$ | $10$ | $10^{14}$ | $820$ | $10^{17}$ |
| $9$ | $10$ | $10^{14}$ | $750$ | $10^{17}$ |
| $10$ | $10$ | $10^{14}$ | $720$ | $10^{17}$ |
範例測試不屬於任何群組。你可以解決它,但請注意,即使不解決它也有可能獲得滿分。
實作細節
範例錯誤解法與範例函式庫(C++ 與 Python)位於 SIO2 的「檔案」區塊中。這些解法與函式庫展示了所有函式所接收與回傳的型別。範例函式庫的行為可能與評測時使用的不同,且可能不符合題目要求。它們僅用於展示與程式互動的方式。
C++ 解法 dzi.cpp 可透過以下指令編譯:
g++ -O3 -static -o dzi dzi.cpp dzilib.cpp -std=c++20
請確保 dzilib.h 與 dzilib.cpp 檔案與你的解法位於同一個資料夾中。
Python 解法 dzi.py 可透過以下指令執行:
python dzi.py
請確保 dzilib.py 檔案與你的解法位於同一個資料夾中。
程式執行後,函式庫會在標準輸入中依序讀取 $t, n, q$ 與 $c$ 的值,接著讀取各個隱藏數值 $x$。對應範例測試的輸入檔案名稱為 dzi0.in,可在兩個封存檔中找到。