Author: toxicpie
Setter: erd1
題目:給定棋盤上皇后的位置,請輸出有多少對皇后互相攻擊。
暴力枚舉兩個皇后,再枚舉有沒有第三個皇后擋在他們中間。
複雜度:
維護四個 map
,每個代表第 key
個直(橫、斜)排有 val
個皇后。
答案就是
複雜度:
抱歉卡了點常數。 ><
畢竟肥的
順便讓各位練習全國賽被垃圾題卡常的心態調整(X
官解的做法是把輸入的 sort
,答案就是四個陣列的 v.end()-unique(v.begin(), v.end())
的和。 當然,胖一點點可能還是能過,但是開到 set
或 map
或 lower_bound
太多次就會太胖。
複雜度:
注意到 unordered_map
(或 cc_hash_table
等)的複雜度只有在輸入是隨機的時候才是平均
Author: HNO2
Setter: double
題目:給定一張有向無環圖,請判斷是否有一條哈密頓路徑。若有,請輸出一個。
可以觀察得到 DAG 上的 Hamilton 路徑存在若且唯若拓樸排序唯一,此時的拓樸排序就會恰為其 Hamilton 路徑,於是
Author: SorahISA
Setter: casperwang
題目:給定一個矩陣,請計算有多少個十字形區域滿足左右臂等長,上臂比下臂短,且最大值發生在交叉點。
只要考慮上下的情形即可,對每個權重大於左右兩邊的中間位置,用單調隊列找出一個位置可以分別大於上下的多少格並用 Subtask 5 的算式計算答案。
對每個位置,
總複雜度是
期待看到神奇的唬爛作法(?)
用單調隊列找出一個位置可以分別大於上下左右的多少格,並以 Subtask 2的方法計算答案。
計算答案的公式可以優化如下
總複雜度是
Author: SorahISA
Setter: SorahISA
題目:有
限制:
既然
時間複雜度:
限制:
對於一組給定的拳,顯然你可以在
int N, M;
string X, Y; /// 對方的拳是 X;你的是 X
int score = 0;
for (int i = 0; i < N; ++i) {
if ((X[i%M] == 'R' and Y[i] == 'P') or
(X[i%M] == 'P' and Y[i] == 'S') or
(X[i%M] == 'S' and Y[i] == 'R')) --score; /// lose
else if (X[i%M] != Y[i]) ++score; /// not lose and not tie
}
所以只要枚舉所有出拳的方法就可以 AC 了!
時間複雜度:
限制:
觀察出愛一個位置
現在題目被簡化成如下的樣子:給你
是經典的背包題,透過 DP 來處理可以組成的數字。令
最後就
請記得處理邊界、超出範圍的問題,且要把
時間複雜度:
上面 DP 的轉移式是經典的湊數字背包問題,可以使用
bitset<2*maxn+1> dp[M+1];
dp[0][maxn] = 1;
for (int i = 1; i <= M; ++i) {
auto [winR, winP, winS] = win_val[i-1];
if (winR > 0) dp[i] |= dp[i-1] << winR;
else dp[i] |= dp[i-1] >> -winR;
if (winP > 0) dp[i] |= dp[i-1] << winP;
else dp[i] |= dp[i-1] >> -winP;
if (winS > 0) dp[i] |= dp[i-1] << winS;
else dp[i] |= dp[i-1] >> -winS;
}
時間複雜度:
去年的全國賽也有需要使用
Author: erd1, double
Setter: enip
Statement: joylintp
題目:有一些組別在排隊,有兩種操作:
要怎麼知道第
接下來,我要知道,對於這一組,它被旋轉了幾次。然後我們可以發現,對於同樣長度的隊伍,被旋轉的次數是一樣的。因此我們只要對每個長度
操作 2 的時候,就是對兩個資料結構單點/區間加值之類的,取決於你用了哪種資結。
Author: HNO2
Setter: HNO2
題目:給定一棵有根樹,這棵樹不計根節點一共有
注意到葉子數量很少,所以可以暴力找出新圖有哪些邊以後,再對新圖做哈密頓路徑的位元 DP。
找新圖的邊的部份可以使用對每個
找哈密頓路徑的部份是經典問題,可以在
這個 Subtask 以後需要用到一個性質:如果原問題有解,則一定有一個解是將所有葉子依照某個 DFS 順序而成。(簡略說明見下方)
因此可以發現對於定根
有了上面那個性質以後,可以發現最多只有一個子樹,他的所有葉子走完以後無法回到
使用樹 DP。令
要構造一組解也十分容易,記住哪個子樹要最後走以後,剩下的子樹依照任意順序繞即可。時間複雜度為
考慮給定根
這樣持續交換下去就能讓同一棵子樹底下的葉子全部併在一起。之後對每個子樹遞迴做下去就是一個原樹的 DFS 順序了。
Author: erd1
Setter: erd1
題目:已知區域的地形分布是帶狀的,在每一個區域的移動速率是定值。請問兩點之間的(時間)最短距離。
距離除以速度加起來不虧。
複雜度
路徑一定是在地形交界處轉折,而且轉折點對時間的函數是凸(或凹)的。
因此可以對他三分搜。
複雜度
這題其實是物理題。司乃爾定律告訴你最短路徑一定滿足
複雜度
最後是精度問題。
你只要想像如果有一塊的速度超大,其他都超小,那你在其他段的路徑應該幾乎是平的,然後只有在那一段超斜。所以如果你在其他段的角度稍微動一下,你在那段的角度應該會動超級多,然後你就噴掉了。
對最斜的那段的角度二分搜也是沒用的,因為你的角度會很接近
因此正確的做法應該是求出
Let
To calculate the root
你只要想像如果有一塊的速度超大,其他都超小,那你在其他段的路徑應該幾乎是平的,然後只有在那一段超斜。所以如果你在其他段的角度稍微動一下,你在那段的角度應該會動超級多,然後你就噴掉了。
對最斜的那段的角度二分搜也是沒用的,因為你的角度會很接近
因此正確的做法應該是求出
Suppose
We ought to calculate
Thus if
And thus
Which could skyrocket when
The same thing occurs if
And thus
Which still wouldn't work when
Now suppose
You could already see that the
And indeed
Thus to obtain the answer with a relative precision of
Given
A potential culprit of numerical instablility is the subtraction, but by expanding the term,
This can still be calculated presicely (as
Author: toxicpie
Setter: toxicpie
題目:給
只要能吃到
時間
對於任意的吃蛋方案,我們可以把所有吃蛋時間盡量往後推,變成在
把
時間
假設有某種方法可以吃
時間
考慮 Subtask 2 的做法,但是分成兩個版本:
如果以上的答案都不是
這邊用到的性質可以在下面的 Proofs 找到。
時間
Subtask 2, 3 的順序和分數好像應該要互換?
令
如果
由 Subtask 3 可以知道,如果
直接求
時間
TBA
Author: erd1, HNO2
Setter: erd1
題目:給定一棵樹,每個點上面有水。每次詢問是戳一個點,所有點的水匯往該點走一步,並輸出點上原有的水量。
暴力模擬。
暴力模擬。只要遇到沒水的點就直接break
掉。但是一開始水可能不聯通,所以這樣會 WA。你只要初始化時給每個人一個 pair<int, bool>
)。
因為樹是隨機生成的,你去估計每個人的深度總和你會發現他是均攤
拿 treap
暴力模擬。
先假設一開始的水都是連通的而且每次一定會戳出水來。有水的區域一定是一個連通塊 treap
維護。每次花
又因為每次戳完,有水的點會減少
一開始有沒水的點的處理方式與 Subtask 2 相同。
如果現在戳了沒水的點,有水的點只會至多多一個(
這題根本暴力模擬題,唯一的難度就只有維護那個大便結構。出題者寫了三個小時的官解,加上中間受不了跑去休息的三個小時,以及寫完以後除了四個小時的蟲,總共花了十個小時。負責驗題的大概斷斷續續奮鬥了兩三天最後放棄了QQ