mount
我們會驚奇的發現,無論網格在哪裡,只要有山覆蓋了,那麼這裡的貢獻一定是 \(\sqrt{2}\),如下的圖可以證明:
那麼我們就只用開一個線段樹,維護的是最小值和最小值的出現次數,如果最小值不為 \(0\),那麼這部風就沒有貢獻,反之貢獻就要加上最小值的出現次數
細節
由於我們可以直接把山峰轉換成 \([max(0ll, x - y), min(w, x + y)]\),但是由於取了個 \(min\) 和 \(max\) 有可能把兩座山峰判成同一組,所以我們還要記錄最開始的 \(x, y\)
nac
我們可以發現,設 \(a, b, c\) 分別表示當前子序列 \(N, NA, NAC\) 的出現次數,那麼我們可以得到如下程式碼
for (int i = 1; i <= n; i++) {
if (s[i] == 'N') {
a++;
}
else if (a[i] == 'A') {
b += a;
}
else if (a[i] == 'C') {
c += b;
}
}
那麼我們可以設狀態 \(dp_{i, j, k}\) 表示當前有幾個為 \(N, NA, NAC\),那麼我們可以記上一次的轉移,最終遞迴輸出即可