自然組:https://drive.google.com/file/d/1KAaPOYdzBuoC0hXdFwS5W0ZEItY61ktk/view
社會組:https://drive.google.com/file/d/1L-SLEkVPJryKrFpP6bHox1sq0o4rDC3k/view
if else
。
枚舉。
將輸入的蘋果和橘子都和 取餘數,因此會分成四種人。兩個人可以平分若且唯若他們是同一種。假設四種人分別有 個人,則答案是 ,。
題目等價於求以下不定方程的正整數解個數。
可以做 的 DP 得到解數。
此不定方程等價於
這等價於求 寫成四個正奇數的和的方法數。注意到如果是四個平方數的和,必定是四個偶數或四個奇數的平方(平方數模 餘 或 或 )。
故所有奇數解有 個。因為每個變數都可以任意給定正負號,因此答案是 。
根據雅可比四平方和定理,這會化簡成 。
枚舉因數可以 做完。
用個好一點的因式分解方法,例如暴力枚舉到 再用 Pollard's rho 做完,或是 GNFS。
這題在 OEIS 有 QQ
矩陣必定要形如 ,用 if
判就好了,。
你可以將最後一行和最後一列以外的每個元素都 greedy 變成 ,然後判斷最後一行和最後一列是否全為 即可。
事實上每一行和每一列的總和在操作不變,所以你只要判斷每一行每一列的和是不是都是 即可。這只需要 的額外記憶體。
首先注意到
2. 告訴你 rank 至多是 ,而是否能做到 是原題,因此我們只需要判斷答案是否為 。
若矩陣可以消到使得 ,則
因此你知道 的一整列兩兩元素之間的比。
因為第 列的總和是 ,因此你可以算出 的每個元素,亦即
其中 是每個元素的總和。
(當 ,則每一項的分子必須也要有 ,亦即 或 。此時只要把所有東西都消到剩第一行或第一列即可。)
因此你只要檢查對於所有 , 是否是整數。如果是整數答案便為 ,否則答案為 。
暴力枚舉 。
如題敘 。
預處理模逆元可以線性做到。給定 時,會是一個 的三次方程,因此要嘛至多 個解,要嘛所有 都是解。因此利用 bucket sort 也可以去掉最後排序的 。因此這可以做到 。
一些 random ramble
暴力枚舉 。
參見Schoof's algorithm。以下簡述做法。
或 的情況一樣要分開處理。以下假設 。
注意到題目沒有保證輸入是橢圓曲線,因此我們要先檢查他的判別式。
若 的判別式 ,則他不是光滑的。
若,則。每個 都對到一組解,而也是一組解。總共 組。
否則令,式子會變成 。注意到每個 都可以對到一組解,除非此時 。另外還有 的那組。
因此若 模 是平方數,則只有 組解。否則是 。
接著處理橢圓曲線的情形。眾所周知,橢圓曲線上的點形成一個群,而事實上這個群一定是兩個循環群的積(, )。根據 Hasse's theorem,若 上的橢圓曲線有 個點,則。因此我們隨便抓一個曲線上的點 ,並對在那個區間中尋找滿足 的 。如果只有一個 我們就做完了。否則就挑另一個點再做一次。這是 的,因為每次在曲線上做加法都要一個 。
但前提是,這個隨機是好的。但好巧不巧他是爛的。如果你跟著維基百科做會TLE。
例如 的群在 的時候會同構於。因此每個點在那個區間都會有至少兩個 滿足 ,因此你永遠戳不到一個好的點。這個例子是在 這篇論文 找到的。
但是考慮曲線 ,其中 是任意一個非二次剩餘。這個曲線滿足 ,而且你可以證明,如果 ,則 或 上至少有一個點是好的。因為他是兩個循環群的積,所以事實上那條曲線上大多數的點都是好的(因為)。
因此,你就只要在兩個曲線上交互戳點即可。複雜度 。
以上沒有證明的東西應該都可以在 這篇論文 找到證明。
在那個區間做大步小步,可以做到 。
另外,維基百科上面還有多項式時間的做法,例如 SEA演算法 是 的。但是我找得到的他的實作都是上千行的,所以應該不適合當題目(?
然後其實這題意外好寫,要是我早點發現他就會跑到自然組了(X
窮舉所有區間,每個區間 求最大值、最小值檢查。
共
窮舉區間的左界,嘗試讓右界不斷遞增並同時維護最大和最小值,共 。
觀察到 的作法中,每個左界看到合法的最遠右界是非嚴格遞增的,因此可以使用雙指針維護,最大最小值則因為序列遞增能 得出。
。
使用雙指針並配合 multiset 或線段樹等可維護區間極值的資料結構控制全距。
維護區間極值時可以使用兩個 deque 維護兩種單調隊列,如此一來可以將複雜度壓到 。
或用 RMQ
對每個詢問做一次原題 。
莫隊 。可能有不帶 的做法可是我不在乎。
你可以算出在 結束的區間最長可以從哪裡開始並稱他為。
則詢問 的答案是
將第二項拆解後可得
後兩項皆各為一個二維偏序問題,可以離線用 BIT 等資料結構完成 (或吉如一)。總複雜度是 。
不失一般性假設 :
如果 ,輸出 。
如果 ,由於小 E 不停在兩個地點間往返,小 C 無法回頭,因此答案為 。
如果 ,輸出 。
和前一子題類似,但是當 ,考慮 是否有環。
如果 有環,輸出 。
否則輸出 上的最遠點對距離(樹直徑)。
假設 。
構造新圖 ,其中 且 。
枚舉 建圖。
若 有環,答案為 。
否則對於每個連通塊計算樹直徑,輸出最大值。
樹直徑的計算可以使用平方時間的方法,不影響整體時間複雜度。
延續 Subtask 3。
對於所有 ,紀錄 裡有哪些 的邊滿足 。
枚舉 的邊 時直接查詢 對應的邊,建圖時間化為 。
雖然 的量級是 ,但是當 時必定有環,因此最終時間複雜度降為 。
此子題的樹直徑須以線性時間計算,由於相關資料容易取得,於此不加贅述。
方便起見,以下假設 。
Note 1: 此題建圖有 的做法,基本上無法通過測試。
Note 2: 假設 -bit integer 的四則運算、位元運算和比較等等都是 ,建圖有 的做法,也能通過此題(提示: bitset)。
答案是 。
注意到一定要有一個鬧鐘設定響的時間是這個序列的最小值(也就是 ), 而且很顯然這個鬧鐘只能由第 個人設定。因此,前 個人起來的時間點只能是 ,便證明了上面那個答案的上界。
欲證明這個答案是下界也很簡單: 讓第 個人設置鬧鐘在 響,再對於 ,設置一個鬧鐘在 響起即可。
因為每個人來的時間點不是 就是 ,因此相當於最小化 但是起來時間點是 的人。令序列 為每個人最後起來的時間點,則不難發現: 在序列 中, 的連續段長度至少要是 。這是因為,如果有一段連續段長度不足 ,則沒有地方可以擺設鬧鐘。
則這個問題可以轉換為: 使用一些長度為 的區間覆蓋 ,且把所有 都覆蓋的情況下,最少能覆蓋幾個 。這個問題可以使用一個簡單的DP解決: 令 代表前 個數字所有 都覆蓋的情況下,最少能蓋到多少個 。轉移如下:
其中 代表 區間中 的個數。
考慮 狀態 代表:把區間 設好,並且指使用前 小的數字的情況下,每個人可以睡覺的最大時間總和。
general 的轉移: 。
此外,如果 比第 個數字還大的話,還可以考慮轉移 , 的轉移類似。
除此之外,還要考慮轉移 。
複雜度就是
這是一個測題者寫出來很奇怪的解ww
有多種作法,以下只介紹其中一種。
令 為序列 中最小值的出現位置。則可以發現,至少要有一個鬧鐘覆蓋位置 ,設置時間在 時間點響。假設這個鬧鐘設在位置 ,則由於每個鬧鐘影響範圍都一樣,且這個鬧鐘響起的時間是最早的, 左邊和右邊的鬧鐘不會互相干擾。
經由以上觀察,可以得到以下 DP 解: 令 代表在位置 各設置一個鬧鐘的情況下, 這個區間的人最大的睡眠時間總和。若 則 為 。否則,令 為區間 最小值發生點,轉移為 。也就是算出左右兩邊的DP值後再計算這個鬧鐘可以讓多少人起來。時間複雜度 。
前面 4 個 Subtask 跟自然組一樣就不贅述了。
跳脫一下前面區間 DP 的想法。在 Subtask 2 中提到,在序列 中, 的連續段長度至少要是 。在 General 的情況也有一個很類似的結論: 如果在序列 區間 數字都一樣,且滿足 ,則這個區間的長度至少為 。若稱這種區間為一個「長區間」,則會發現任意兩個長區間 必為先遞增後遞減。
這樣子整個 DP 的雛型就出來了: 令 代表序列 中,最後一個數字一樣的區間結尾在 ,他的值是 (需將輸入的數字先離散化)。 代表狀態: 代表前一個區間的數字比他大, 代表比他小, 代表他處在一個長區間的結尾。
轉移的話基本上只要注意「任意兩個長區間 必為先遞增後遞減」,也就是除了 不能轉 以外其他都可以轉。轉移的時候可以使用前後綴 加速轉移,詳細轉移有些繁瑣就不附上來了。
最後答案是 的最大值。總時間複雜度是 。
tmw 宣稱這題可以做到 和 ,需要用到 CHT 線段樹等工具。只是因為我不會(X)就沒出進社會組了。
因為木製柵欄不用錢,所以我們可以直接讓他超長。以下用 來表示白銀柵欄長度為 ,木製柵欄超長,且矩形重心的極角為 的矩形。注意到蓋出 的花費是 。
可以發現若 同時包含 和 ,那 一定是 或 。如果選擇 ,那麼該矩形會蓋住所有 且 的點。因此答案是所有樹的 座標絕對值中的最大者 。
時間複雜度:
固定 的值,考慮 能蓋住 時 的條件:
也就是說, 的可能值一定是一個區間 (可以在腦中想像旋轉那個矩形,應該會很直觀 (?))。如果給定一個 ,那寬度 的矩形能蓋住所有點若且唯若每棵樹對應的 區間的交集非空,而這可以在 的時間內判斷。
因此,我們可以對答案二分搜。時間複雜度:,其中 且 是允許的誤差。
做法 2 正確性的證明可能會需要 EX 版題解的某些 lemma ,但是在賽中應該不難猜出並相信結論是對的 (?),並且實作拿到 AC。
假設不是所有點都在 軸上。令 是一個最佳解,且 分別是所有可行解 中, 的最小和最大值。可以想像 連續的從 轉到 時都會有可行解,且對應的最小寬度在 會遞減,而在 會遞增。
因此,我們可以對 做三分搜來找矩形寬度的最小值。時間複雜度: ,其中 且 是允許的誤差。
注意: 如果你寫了這兩種做法且常數很大 (像是使用了 long double
或是搜太多次),那 Subtask 4 很有可能不會過。
小知識:這題的浮點數版本才是原本的 pG。
注意到 Subtask 1 等價於柵欄要圍住所有樹。觀察到有解若且唯若存在一條過原點的直線,使得所有樹都在他的同一側,所以極角排序後就可以簡單判斷有沒有解。
假設有解,且最佳解長這樣:
那麼,他一定會滿足這些條件:
簡單的處理一下這些條件後,可以知道以下三點至少有一點會成立:
因此可以分 case 找答案,取其中的最小值。
若 上有一棵樹,則答案為所有點的向量投影到 上長度的最小值 ,即
,其中 是 上的一棵樹。
而 最直觀的找法,就是求原點到所有樹凸包的右切線。
同上,答案為
,其中 是原點到所有樹凸包的左切線 (他會在 上)。
(這是實作較簡單的做法,其他做法如旋轉卡尺等也可以用。)
考慮所有樹對原點做對稱之後複製一份,如下圖:
可以發現,兩條木製柵欄分別為原本的樹和對稱後的樹的凸包切線,而答案即為原點到切線距離的 4 倍。不過,在更新答案之前,我們需要先檢查是否所有樹都在 的同一側。
時間複雜度:
總共為 。
其實作法同 Subtask 3 ,只是實作上會簡單不少。
我們需要找到一棵樹,使得砍掉他後,包住剩下的樹所需的矩形寬度會最小。有兩種情況:
由 subtask 1 的解法可以發現,砍掉一棵樹之後必須滿足以下其中一種,答案才有可能變小。
再利用一次上面的性質,可以知道砍樹前的最佳解一定會是以下 case 的一種。
總時間複雜度一樣是 。
Remark: 為何所有輸出的 都不會是 的倍數呢?可以發現,以上所有 case 中算出的答案分母都是某兩個格子點之間的距離,也就是說,,其中 是整數。由於 不是 的二次剩餘, 只有在 才會滿足,而這在測資中不可能發生。
Floyd-Warshall + DP。
可以先對每個點對計算最小花費,之後再使用Floyd-Warshall。複雜度 但常數很小。
建圖
對於每一個節點,計算用價格最高可以達到的節點()。之後再用倍增算出最少需要多少花費才能抵達節點 。
對於每一個節點,計算用價格最高可以達到的節點()。
對於每一個詢問,一個詢問可以分成和。我們可以計算最少要從和到LCA的價格為和。如果有路連通和,答案就是。如果沒有,答案就是。找路可以用2D區間和,或者可以可以在樹壓平用BIT維護:
結合Subtask4和Subtask5。先對於每一個節點,計算用價格最高可以達到的節點()。之後可以發現對於每個點對 ,計算最少要從和到LCA的價格為和。之後需要找是否有權重 的路連通 與 ()。找路一樣可以使用之前介紹的方法。
可以把三個數字塞進一個數字。
這題的 Subtask 4 在 CF 上有,出出來以後就發現撞題了 QQ