雅禮國慶集訓
阿新 • • 發佈:2018-12-13
前言
灑落君臣契,飛騰戰伐名。(杜甫《公安縣懷古》)
NOIP 前的一個月。
這浸滿熱血的虔信,真的會化作墓碑嗎?
或許明日我們不再是戰友,但人生終將有無數個此時。
本文省略以下定義:
#define F(z, u, v) for(int z = (u), des##z = (v); z <= des##z; ++z)
struct Bnd { int f, s; Bnd(int f = 0, int s = 0): f(f), s(s){}}
struct Tup { int f, s, t; Tup(int f = 0, int s = 0, int t = 0): f(f), s(s), t(t){}}
template <typename T> bool chkmax(T& a, T b) { return a < b ? a = b, 1 : 0; }
本文所有原始碼由命題者提供,格式已調整,並加了註釋。
亂入
填一下暑假清北血糖的坑。
複習 維護區間取模、單點修改、區間和。
所以今年暑假我才會寫線段樹,我太弱了… 記錄和的同時記錄一個最大值,如果最大值小於模數就跳過即可。
Garden 給定點集 ,在矩陣 上找兩點 使 最大,其中 ,點按照向量運算。
棘手的問題在於重複。事實上根據抽屜原理,每個點只需選 個,就會有一個不重複的。因此每個點最大的 個即可。
D1
養花 靜態區間詢問模以某數後的最大值。
分塊。 預處理所有除數的結果,塊外暴力,塊內查表。
F(i, 1, bn) { memset(lst, 0, sizeof lst) ;
F(j, (i - 1) * bs, std::min(i * bs, n)) lst[a[j]] = a[j];
F(j, 1, MAXQ) chkmax(lst[j], lst[j - 1]); // lst[j] 為 j 前最大值
F(j, 1, n) for(int k = 0; k <= MAXQ; k += j)
chkmax(ans[i][j], lst[std::min(k + j - 1, MAXQ)] - k); }
// 取所有 [ik, (i + 1)k) 內最大值
折射 平面上有若干定點,過之作折線,使縱座標遞增且橫座標擺幅減小,求方案數。
字首和優化。 縱向轉移需要 ,故橫向轉移。 代表節點 為頂端,向左/右的方案數。加入一新節點時其在最右,故必在首位或次位。
F(i, 1, n) { dp[i][0] = dp[i][1] = 1;
for(int j = i - 1; j >= 1; j--)
if(p[j].y > p[i].y) (dp[j][1] += dp[i][0]) %= MOD;
else (dp[i][0] += dp[j][1]) %= MOD;
ans = MOD - n; F(i, 1, n) ans = ((ans + dp[i][0]) % MOD + dp[i][1]) % MOD;
畫作 在 01 矩陣上每次可以為一個四連塊塗色,求從白色畫出給定圖形的最小步數。
搜尋。 最優方案總能等價成一種修改範圍逐步縮小的方案。因此,我們可搜尋末態的所有點,它所需的塗色次數為最遠的黑塊加 1(「最遠」是經過的四連塊最多),爾後取最小值即可。
int bfs(int x, int y) {
static const int dx[] = { 1, 0, -1, 0 }, dy[] = { 0, 1, 0, -1 }; // 一步之遙
std::deque<pii> q; memset(dis, -1, sizeof dis);
dis[x][y] = 0; q.push_back(Bnd(x, y));
int re = 0; while(!q.empty()) {
int cx = q.front().f, cy = q.front().s; q.pop_front();
if(g[cx][cy] == '1') chkmax(re, dis[cx][cy]);
for(int i = 0; i < 4; ++i) {
int nx = cx + dx[i], ny = cy + dy[i];
if(nx >= 0 && nx < n && ny >= 0 && ny < m && dis[nx][ny] == -1)
if(g[nx][ny] == g[cx][cy])
dis[nx][ny] = dis[cx][cy], q.push_front(Bnd(nx, ny));
else dis[nx][ny] = dis[cx][cy] + 1, q.push_back (Bnd(nx, ny)); }}
return re; }
// 主函式內:
ans = INF; F(i, 1, n) F(j, 1, m) chkmin(ans, bfs(i, j));
printf("%d\n", ans + 1);