# Site URL: https://blog.rusin7.com ## Archives URL: https://blog.rusin7.com/archives A list of all the years of creating my posts # Archives ## 2026 32 posts - [2026/09/29 单源最短路算法 ](/article/shortest-path) - [2026/08/31 Cyanwind 主题 markdown 语法 ](/article/how-to-use-markdown) - [2026/08/13 Rusin note 项目推荐 ](/article/rusin-note) - [2026/01/11 MDX 组件使用:User & Advanced ](/article/mdx-components) - [2026/01/11 写作指南:Markdown / MDX ](/article/writing-markdown-mdx) - [2026/08/11 在 VPS 上部署洛谷保存站 ](/article/deploy-lg-saver) - [2026/08/03 博客迁移分流说明 ](/article/explanation-of-blog-migration) - [2026/07/22 洛谷网校 CSP 初赛笔记 ](/article/luogu-class-csp-j-note) - [2026/06/07 在 Hexo 中复现洛谷插件 ](/article/luogu-plugin-in-hexo) - [2026/06/07 笔记——树形动态规划 ](/article/notes-of-dp-on-trees) - [2026/06/06 题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ! ](/article/at-pakencamp-2020-day1-d-sol) - [2026/06/06 AC 自动机笔记 ](/article/automated-ac) - [2026/06/06 JC 提高班期末测试题解 ](/article/jc-the-end-of-class-test-solution) - [2026/06/06 题解:P13361 \[GCJ 2011 Qualification\] Bot Trust ](/article/p13361-sol) - [2026/06/06 题解:P8506 标题计数 ](/article/p8506-sol) - [2026/06/06 题解:P8534 「Wdoi-2」比赤色更红的梦 ](/article/p8534-sol) - [2026/06/06 网络流笔记 ](/article/the-network-flow-notes) - [2026/05/14 拯救谷歌和 Github!你的新“自行车” ](/article/devsidecar) - [2026/05/12 Vercel 仅部署指定分支的方法 ](/article/vercel-deploying-only-1-branch) - [2026/04/20 对单一仓库配置小号以远程管理小号仓库 ](/article/configure-a-single-warehouse) - [2026/04/19 在 VS code 上远程管理 Github 仓库并自动化部署项目 ](/article/remote-github-repo-on-vs-code) - [2026/04/06 侧边栏添加个性定位欢迎信息 ](/article/location-welcome-information) - [2026/04/03 第22届浙大宁波理工学院程序设计大赛题解 ](/article/22nd-zhejiang-competition-solution) - [2026/04/03 在 arm64 中安装虚拟环境 ](/article/arm64-install-base) - [2026/04/03 图论之欧拉回路、差分约束——算法笔记 ](/article/euro-circuit-notes) - [2026/04/03 题解:P14702 \[ICPC 2024 Tehran R\] Boat ](/article/p14702-sol) - [2026/04/03 题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree ](/article/p14731-sol) - [2026/04/03 我常常追忆过去 ](/article/remember-the-past) - [2026/03/30 题解:AT\_joi2024\_yo1c\_b 桁 (Digit) ](/article/at-joi2024) - [2026/03/30 题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type ](/article/p14730-sol) - [2026/03/23 题解:CF2139B Cake Collection ](/article/cf2139b-sol) - [2026/03/23 免费获取二级域名并部署 github 仓库 ](/article/free-domain) --- ## 第22届浙大宁波理工学院程序设计大赛题解 URL: https://blog.rusin7.com/article/22nd-zhejiang-competition-solution 本文讲述了第22届浙大宁波理工学院程序设计大赛的 C++ 代码。 ![第22届浙大宁波理工学院程序设计大赛题解](https://image.rusin7.com/file/hexo/cover/VdGvvMhu.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/VdGvvMhu.webp) 2026/04/03 15 分钟 [题解](/tags/题解) / [比赛](/tags/比赛) # 第22届浙大宁波理工学院程序设计大赛题解 > 本文讲述了第22届浙大宁波理工学院程序设计大赛的 C++ 代码。 次阅读 [| 次评论](#waline) ## A. 字符串[#](#a-字符串) 按照题意模拟即可,如果想要省掉代码量可以开个 `std::vector> ve(n)` 前一个记录字符,后一个记录当前的下标,直接进行升序排序,然后直接从k+1个开始输出。 提供排序的代码。 ``` void clearlove13(void){ int n, k; std::cin >> n >> k; std::string s; std::cin >> s; std::vector> ve(n); for (int i = 0; i < n; i++) { ve[i] = std::make_pair(s[i], i); } std::sort(ve.begin(), ve.end()); std::vector> ans; ans.reserve(n); for (int i = k; i < n; i++) { ans.push_back({ve[i].first, ve[i].second}); } std::sort(ans.begin(), ans.end(), [&](auto & a, auto & b) { return a.second < b.second; }); for (auto &[x, y] : ans) { std::cout << x; } } ``` cpp ## B. 价格跨度[#](#b-价格跨度) 题意大概就是求该 aia\_iai​ 前面第一个大于该 aia\_iai​ 的位置,从题目数据可得知,此题我们需要使用 O(n)\\mathcal{O(n)}O(n) 复杂度来写这道题,思考一下可以使用单调栈来实现,只需要等效思想来写即可。 ``` void clearlove13(void) { int n; std::cin >> n; std::vector a(n + 1); for (int i = 1; i <= n; i++) { std::cin >> a[i]; } std::vectorst; std::vector ans(n + 1); st.reserve(n + 1); for (int i = 1; i <= n; i++) { while (!st.empty() && a[st.back()] <= a[i]) { st.pop_back(); } if (st.empty()) { ans[i] = i; } else { ans[i] = i - st.back(); } st.push_back(i); } for (int i = 1; i <= n; i++) { std::cout << ans[i]; if (i != n) std::cout << ' '; } } ``` cpp ## C. 斐波那契数[#](#c-斐波那契数) 事实上题目已经告诉你了做法直接模拟即可。 ``` i64 a[51]; void clearlove13(void) { int n; std::cin >> n; std::cout << a[n] << '\n'; } int main(void) { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); a[1] = 1; a[0] = 1; for (int i = 2; i <= 50; i++) { a[i] = a[i - 1] + a[i - 2]; } int cas = 1; std::cin >> cas; while (cas--) clearlove13(); return 0; } ``` cpp ## D. 回收礼物[#](#d-回收礼物) 设 f(x→y)f(x\\to y)f(x→y) 是以 111 为根 ,求x到y的树上最小路径 我们先了解题意,就可以明白是需要求形如 f(1→2)+f(2→3)+f(3→…)+f(…→2)f(1\\to 2)+f(2\\to 3)+f(3\\to \_{\\dots})+f(\_{\\dots}\\to 2)f(1→2)+f(2→3)+f(3→…​)+f(…​→2) 这么一个式子,那么我们应该怎么快速去求树上最短路径呢?引入lca求最近公共祖先,有一个小trick就是我们 所以我们就先求出到两个点的深度之和再减去公共祖先的深度就可以写出这道题了。 ``` struct LCA { int n, lg; std::vector> up; std::vector depth, tin, tout; int timer = 0; LCA(std::vector>& ed, int root = 0) { n = int(ed.size()); lg = std::__lg(n) + 1; up.assign(n, std::vector(lg)); depth.assign(n, 0); tin.resize(n), tout.resize(n); auto dfs = [&](auto self, int u, int p) -> void { tin[u] = timer++; up[u][0] = p; for (int i = 1; i < lg; ++i) up[u][i] = up[up[u][i - 1]][i - 1]; for (int v : ed[u]) { if (v == p) continue; depth[v] = depth[u] + 1; self(self, v, u); } tout[u] = timer++; }; dfs(dfs, root, root); } bool is_ancestor(int u, int v) { return tin[u] <= tin[v] && tout[v] <= tout[u]; } int get_lca(int u, int v) { if (is_ancestor(u, v)) return u; if (is_ancestor(v, u)) return v; for (int i = lg - 1; i >= 0; --i) if (!is_ancestor(up[u][i], v)) u = up[u][i]; return up[u][0]; } std::vector get_path(int u, int v) { int w = get_lca(u, v); std::vector up_path, down_path; while (u != w) { up_path.push_back(u); u = up[u][0]; } up_path.push_back(w); while (v != w) { down_path.push_back(v); v = up[v][0]; } std::reverse(down_path.begin(), down_path.end()); up_path.insert(up_path.end(), down_path.begin(), down_path.end()); return up_path; } }; void clearlove13() { constexpr int lg = 20; int n, q, rt; std::cin >> n >> q ; rt = 1; std::vector> g(n + 1); std::vectorch(q); for (int i = 2; i <= n; i++) { int u; std::cin >> u; g[u].push_back(i); g[i].push_back(u); } std::vector dep(n + 1); std::vector> up(n + 1); for (int i = 1; i <= n; i++) { std::fill(up[i].begin(), up[i].end(), -1); } auto dfs = [&](auto self, int u, int fa) -> void { up[u][0] = fa; for (int i = 1; i < lg; i++) { if (up[u][i - 1] != -1) { up[u][i] = up[up[u][i - 1]][i - 1]; } } for (int v : g[u]) { if (v != fa) { dep[v] = dep[u] + 1; self(self, v, u); } } }; dfs(dfs, rt, -1); auto lca = [&](i64 u, i64 v) -> int { if (dep[u] < dep[v]) std::swap(u, v); i64 d = dep[u] - dep[v]; for (int i = 0; i < lg; i++) { if (d >> i & 1) u = up[u][i]; } if (u == v) return u; for (int i = lg - 1; i >= 0; i--) { if (up[u][i] != up[v][i]) { u = up[u][i]; v = up[v][i]; } } return up[u][0]; }; auto dist = [&](i64 u, i64 v) -> int { i64 l = lca(u, v); return dep[u] + dep[v] - 2 * dep[l]; }; for (auto &i : ch) { std::cin >> i; } i64 ans = dist(1, ch[0]); for (int i = 1; i < q; i++) { ans += dist(ch[i - 1], ch[i]); } std::cout << ans << '\n'; } ``` cpp ## E. 我们都是小怪兽 (Rescue Qfish)[#](#e-我们都是小怪兽-rescue-qfish) 推导公式发现边权每 444 步循环。利用分层图思想,将每个点按时刻拆为 444 层,层间连边,跑 Dijkstra 最短路即可。提供建图的代码。 ``` for (ll i = 1; i <= m; i++) { cin >> u >> v >> w; ll w0 = w; //第一层是L ll w1 = (w - 1) * quickpow(w + 1, md - 2, md) % md; //第二层是(L-1)/(L+1) ll w2 = -quickpow(w, md - 2, md) % md; //第三层是(-1)/L ll w3 = (w + 1) * quickpow((1 - w + md) % md, md - 2, md) % md;//第四层是(L+1)/(1-L) 每四次循环 if (w1 < 0) w1 += md; if (w2 < 0) w2 += md; if (w3 < 0) w3 += md; g[u].push_back({w0, v + n}); g[v].push_back({w0, u + n}); g[u + n].push_back({w1, v + 2 * n}); g[v + n].push_back({w1, u + 2 * n}); g[u + 2 * n].push_back({w2, v + 3 * n}); g[v + 2 * n].push_back({w2, u + 3 * n}); g[u + 3 * n].push_back({w3, v}); g[v + 3 * n].push_back({w3, u}); } ``` cpp ## F. 爱的魔力转圈圈——终极幸存者挑战赛[#](#f-爱的魔力转圈圈终极幸存者挑战赛) 这是一道约瑟夫环问题,但是数据开小了遍历也能过,递推公式: f(n,k)\=f(n−1,k)+k\\mathcal{f(n, k)=f(n-1, k)+k}f(n,k)\=f(n−1,k)+k ``` #include using namespace std; int main() { int n; long long k; cin >> n >> k; long long res = 0; // f(1)=0(1个人时位置为0) for (int i = 2; i <= n; ++i) { res = (res + k) % i; // 递推计算f(i) } cout << res + 1 << endl; // 转换为1-based编号 return 0; } ``` cpp ## G. 探险者的补给路线[#](#g-探险者的补给路线) 直接根据题目意思写就行,x,yx, yx,y 分别是 a,ba, ba,b 的倍数。 ``` void clearlove13(void) { i64 a, b, x, y; std::cin >> a >> b >> x >> y; if (x % a == 0 && y % b == 0 && x >= 0 && y >= 0) { std::cout << "YES\n"; } else { std::cout << "NO\n"; } } ``` cpp ## H. Qfish的法术[#](#h-qfish的法术) 首先我们根据题意每次加2,可以知道区间和无论怎么操作奇偶性永远不会改变,由此延申我们进行分类讨论,如果区间长度是奇数的话,经过操作后的区间和直接贪心成偶数的目标去,因没有要求对操作后的值有具体要求,所以区间长度是奇数就一定可以,如果区间长度为偶数,但区间和为奇数,每次+2并不会改变奇偶性,所以无解。 值得注意的是,我们需要对长度为2的区间进行一个简单的特判,区间和直接用前缀和维护就行。 ``` void clearlove13(void) { int n, t; std::cin >> n >> t; std::vectora(n + 1); for (int i = 1; i <= n; i++) { std::cin >> a[i]; a[i] += a[i - 1]; } while (t--) { int l, r; std::cin >> l >> r; if (r - l + 1 == 2 && (a[r] != a[l - 1])) { std::cout << "NO\n"; continue; } if (((r - l + 1LL) % 2 == 0) && ((a[r] - a[l - 1]) % 2 == 1)) { std::cout << "NO\n"; } else { std::cout << "YES\n"; } } } ``` cpp ## I. 字母混淆[#](#i-字母混淆) 直接根据题目来模拟就行。 ``` void solve(){ string s; int n; cin >> n >> s; s = " " + s; for (int i = 1; i <= n; ++i) cout << (char)((s[i] + 32 - 'a' - 2 + 26) % 26 + 'a'); } ``` cpp ## J. 小s的杀戮尖塔[#](#j-小s的杀戮尖塔) 超级大模拟, 首先我们可以观察到,观者的血量不会超过1000,并且大鄂虫每行动3轮攻击力就会永久增加,而观者每轮理想情况下只能有15点格挡。所以计算可知游戏轮数一定不会超过60轮。因此可以使用三维 dpdpdp 求解。dpi,j,qdp\_{i, j, q}dpi,j,q​,iii 代表第 iii 轮,jjj 代表大鄂虫剩余 jjj 滴血,qqq 代表观者处于的姿态。记录的是观者剩余的血量。每次抽取 555 张牌,用 dfs 记录所有会到达的状态。后面就是漫长的调试代码时间,总复杂度是 O(60×b×3×5)\\mathcal{O(60\\times b \\times 3 \\times 5)}O(60×b×3×5)。而且题目的伤害与大鄂虫的格挡实际上都是3的倍数,因此可以把伤害与血量 ÷3\\div 3÷3 进行计算。实际上由于状态数远不会到达最高复杂度,因此代码可以通过。std 的耗时约 150ms150ms150ms。 一些容易导致 WA 的细节: - 第一轮的行动 111 与后面轮次的行动 111 不同。后面轮次的行动 111 是有 999 点护甲的,第一轮没有。 - 最后 111 轮观者战胜大鄂虫时,游戏立即结算,此时观者不会再受到伤害。 - 把费用用完并不是最优解,例如手里是 555 张暴怒,此时可能会选择一张都不打。 由于出题人的 std 过于臃肿,因此在这里放上能够通过对拍的 AI 代码。 ``` typedef long long ll; ll dp[2][40400][3]; ll num[505050]; struct MoveResult { ll dmg; // 造成的伤害 ll self_blk; // 获得的格挡 ll end_stance; // 结束姿态 }; vector moves_cache[3]; // [起始姿态] -> 结果列表 int main(){ cin.tie(0); cout.tie(0); ios::sync_with_stdio(0); ll t, a, b, n; if(!(cin >> t)) return 0; while(t--){ cin >> a >> b >> n; for(int i=1; i<=n; i++) cin >> num[i]; // 压缩敌方血量 ll max_b = (b - 1) / 3 + 1; for(int x=0; x<=max_b; x++) for(int s=0; s<3; s++) dp[0][x][s] = -1; vector> q; // 队列: {敌方血量, 姿态} q.push_back({max_b, 0}); dp[0][max_b][0] = a; ll ans = -1; ll turn = 0; ll gong = 0; // 力量 while(!q.empty() && turn < 60) { ll cur = turn % 2; ll nxt = (turn + 1) % 2; turn++; // 重置下一轮DP状态 for(int x=0; x<=max_b; x++) for(int s=0; s<3; s++) dp[nxt][x][s] = -1; // 1. 确定手牌 vector hand; for(int i=0; i<5; i++) { ll idx = ((turn - 1) * 5 + i) % n + 1; hand.push_back(num[idx]); } sort(hand.begin(), hand.end()); // 2. 预计算所有出牌结果 for(int s=0; s<3; s++) moves_cache[s].clear(); do { for(int start_s=0; start_s<3; start_s++) { ll c = 3, cur_s = start_s; ll raw_dmg = 0, self_blk = 0; // 记录"一张牌都不出"也是一种可能 moves_cache[start_s].push_back({0, 0, start_s}); for(ll card : hand) { ll cost = (card >= 4) ? 2 : 1; if(c < cost) break; c -= cost; // 伤害计算 ll d = 0; if(card == 1) d = 6; else if(card == 3 || card == 4) d = 9; if(cur_s == 1) d *= 2; // 愤怒翻倍 raw_dmg += d; // 格挡计算 if(card == 2) self_blk += 5; else if(card == 5) self_blk += 8; // 姿态变更 ll old_s = cur_s; if(card == 3) cur_s = 0; else if(card == 4) cur_s = 1; else if(card == 5) cur_s = 2; if(old_s == 2 && (card == 3 || card == 4)) c += 2; // 存入结果 (伤害/3, 格挡, 姿态) moves_cache[start_s].push_back({raw_dmg / 3, self_blk, cur_s}); } } } while(next_permutation(hand.begin(), hand.end())); // 3. 大鄂虫属性计算 ll chong = (turn - 1) % 3 + 1; if(turn > 1 && (turn - 1) % 3 == 0) gong += 5; // 每3回合加一次力量 ll enemy_dmg = 0; if(chong == 1) enemy_dmg = 12 + gong; else if(chong == 2) enemy_dmg = 7 + gong; ll enemy_blk_reduce = 0; if(turn > 1) { ll prev_act = (turn - 2) % 3 + 1; if(prev_act == 2) enemy_blk_reduce = 2; // 6/3 else if(prev_act == 3) enemy_blk_reduce = 3; // 9/3 } vector> next_q; // 4. 状态转移 for(auto &st : q) { ll e_hp = st.first; ll p_stance = st.second; ll p_hp = dp[cur][e_hp][p_stance]; for(auto &res : moves_cache[p_stance]) { // 计算实际对敌伤害 ll dmg_dealt = max(0LL, res.dmg - enemy_blk_reduce); ll next_e_hp = e_hp - dmg_dealt; // 击杀判定 if(next_e_hp <= 0) { ans = max(ans, p_hp); continue; // 敌死,不入队 } // 玩家承伤计算 ll incoming = enemy_dmg; if(res.end_stance == 1) incoming *= 2; // 愤怒易伤 ll take = max(0LL, incoming - res.self_blk); ll next_p_hp = p_hp - take; if(next_p_hp > 0) { if(dp[nxt][next_e_hp][res.end_stance] == -1) { next_q.push_back({next_e_hp, res.end_stance}); dp[nxt][next_e_hp][res.end_stance] = next_p_hp; } else { dp[nxt][next_e_hp][res.end_stance] = max(dp[nxt][next_e_hp][res.end_stance], next_p_hp); } } } } q = next_q; } cout << ans << "\n"; } return 0; } ``` cpp --- ## 在 arm64 中安装虚拟环境 URL: https://blog.rusin7.com/article/arm64-install-base 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 ![在 arm64 中安装虚拟环境](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) 2026/04/03 3 分钟 [git](/tags/git) / [nodejs](/tags/nodejs) / [教程](/tags/教程) # 在 arm64 中安装虚拟环境 > 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 次阅读 [| 次评论](#waline) ## 安装虚拟环境[#](#安装虚拟环境) ### 下载[#](#下载) 下载指定版本: ``` wget https://repo.anaconda.com/miniconda/Miniconda3-py312_24.7.1-0-Linux-aarch64.sh ``` bash 如果官方源下载缓慢,可以试试**国内的清华镜像源**: ``` wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py312_24.7.1-0-Linux-aarch64.sh ``` bash 运行安装脚本: ``` bash Miniconda3-py312_24.7.1-0-Linux-aarch64.sh ``` bash 安装过程中,按照提示操作即可: - 按 `Enter` 键阅读完许可协议。 - 输入 `yes` 接受协议。 - 按 `Enter` 键接受默认安装路径(`/home/user/miniconda3`)。 - **关键一步**:按 Enter 后,安装程序会开始解压文件,然后在接近结束时,一定会问你一个问题,类似: ``` Do you wish the installer to initialize Miniconda3 by running conda init? [yes|no] ``` text 这是问你是否要初始化 Conda 时,务必输入 `yes` 并回车。 重新加载配置文件: ``` source ~/.bashrc ``` bash ### 验证[#](#验证) **重新打开**终端,你会看到终端提示符前面出现了 (base),这就表示安装成功了! ## 安装 Git[#](#安装-git) ``` conda install git ``` bash ### 验证 Git 安装[#](#验证-git-安装) 安装成功后,再次检查 Git 版本: ``` git --version ``` bash 如果输出类似 `git version 2.x.x`,就表示安装成功了。 ### 让 VS Code 识别 Git[#](#让-vs-code-识别-git) ``` which git ``` bash 记下输出。 操作方法: 1. 在 VS Code 中按 `Ctrl + ,` 打开设置。 2. 在搜索框输入 `git.path`。 3. 找到 **“在 settings.json 中编辑”**(点击右上角的文档图标)。 4. 在 JSON 配置中添加(或修改): ``` "git.path": "刚刚的输出" ``` json 5. 保存文件,**关闭 VS Code 再重新打开**。 ## 安装 NodeJs[#](#安装-nodejs) ### 安装 nvm[#](#安装-nvm) 运行以下代码(也可以自己从 [NodeJs 官网 ↗](https://nodejs.org/zh-cn/download) 获得) ``` curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash ``` bash 然后关闭再重新打开一个终端。 ### 安装 Node.js[#](#安装-nodejs-1) 加载后,就可以使用 nvm 安装 Node.js 了。推荐以下两种方式: 1. LTS(长期支持)版本 ``` nvm install --lts ``` bash 2. 安装最新的稳定版本 ``` nvm install node ``` bash 最后输入 ``` npm install -g pnpm npm install -g yarn ``` bash ### 验证[#](#验证-1) ``` npm -v pnpm -v yarn -v ``` bash --- ## 题解:AT_joi2024_yo1c_b 桁 (Digit) URL: https://blog.rusin7.com/article/at-joi2024 本文讲述了如何使用 C++ 完成洛谷的 AT_joi2024_yo1c_b 桁 (Digit),思路清晰、排版精美 ![题解:AT\_joi2024\_yo1c\_b 桁 (Digit)](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/30 1 分钟 [题解](/tags/题解) / [c++](/tags/c++) # 题解:AT\_joi2024\_yo1c\_b 桁 (Digit) > 本文讲述了如何使用 C++ 完成洛谷的 AT\_joi2024\_yo1c\_b 桁 (Digit),思路清晰、排版精美 次阅读 [| 次评论](#waline) [**安利一下自己的博客** ↗](http://blog.rusin7.com "博客") [题目传送门 ↗](https://www.luogu.com.cn/problem/AT_joi2024_yo1c_b "题目传送门") ## 题目大意[#](#题目大意) 给出 a,ba,ba,b,求 a+ba+ba+b 的位数。 ## 思路引导[#](#思路引导) 提问 如何统计 a+ba+ba+b 的位数? 成功 我们将 a+ba+ba+b 转化为字符串函数大法好,输出 a+ba+ba+b 的长度即可。 ## 核心代码[#](#核心代码) ``` #include using namespace std; int a,b; int main() { cin>>a>>b; cout< 本文讲述了如何使用 C++ 完成洛谷的 AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!,思路清晰、排版精美 次阅读 [| 次评论](#waline) ## 问题分析[#](#问题分析) 题目要求计算边长为 NNN 的立方体被平面 x+y+z\=Kx+y+z=Kx+y+z\=K 切割后,包含原点 (0,0,0)(0,0,0)(0,0,0) 的部分体积的 **6 倍**是多少。 立方体的范围为 0≤x,y,z≤N0 \\le x,y,z \\le N0≤x,y,z≤N,平面 x+y+z\=Kx+y+z=Kx+y+z\=K 将空间分为两部分,并且**包含原点的部分**满足 x+y+z≤Kx+y+z \\le Kx+y+z≤K。 ## 核心思路[#](#核心思路) 根据 KKK 与立方体的位置关系,平面切割立方体的效果不同,需分类讨论: - **平面在立方体外部(K≤0K \\le 0K≤0)**:如图 1 ,此时 x+y+z≤Kx+y+z \\le Kx+y+z≤K 不包含立方体任何部分,V立\=0V\_立=0V立​\=0。 ![1](https://cdn.luogu.com.cn/upload/image_hosting/2gwzloc6.png)图1\\tiny\\color{000000}图 1图1 - **平面切割出小四面体(03NK > 3NK\>3N)**:如图 5 ,整个立方体都满足 x+y+z≤Kx+y+z \\le Kx+y+z≤K,V立\=V\_立=V立​\= 立方体体积公式。 ![1](https://cdn.luogu.com.cn/upload/image_hosting/pid9y8n6.png) 图5\\tiny\\color{000000}图 5图5 ## 公式推导[#](#公式推导) - **当 K≤0K \\le 0K≤0** 此时 x+y+z≤Kx+y+z \\le Kx+y+z≤K 无立方体部分,6 倍体积为: > 6×0\=06 \\times 0=06×0\=0 - **当 0 K3K^3K3 - **当 N 3K2N−3KN2+N3−2(K−N)33K^2N - 3KN^2 + N^3 - 2(K - N)^33K2N−3KN2+N3−2(K−N)3 - 当 2N 6N3−(3N−K)36N^3 - (3N - K)^36N3−(3N−K)3 - **当 K\>3NK > 3NK\>3N** 整个立方体都满足 x+y+z≤Kx + y + z \\le Kx+y+z≤K,6 倍体积为立方体体积的 6 倍: > 6N36N^36N3 ## 代码实现[#](#代码实现) 根据上述推导,分情况计算结果: ``` #include using namespace std; long long n,k,res; int main(){ cin>>n>>k; if(k==0){ res=0; }else if(k<=n){ res=k*k*k; }else if(k<=2*n){ res=3*k*k*n-3*k*n*n+n*n*n-2*(k-n)*(k-n)*(k-n); }else if(k<=3*n){ res=6*n*n*n-(3*n-k)*(3*n-k)*(3*n-k); }else{ res=6*n*n*n; } cout< AC 自动机笔记 次阅读 [| 次评论](#waline) ![洛谷炸了](https://cdn.luogu.com.cn/upload/image_hosting/ycm2f9av.png) ![洛谷炸了](https://cdn.luogu.com.cn/upload/image_hosting/akus9280.png) ![洛谷炸了](https://cdn.luogu.com.cn/upload/image_hosting/rktfergq.png) 模板代码([P3808 AC 自动机(简单版) ↗](https://www.luogu.com.cn/problem/P3808)) ``` #include using namespace std; int n,tot,cnt[1000005],ch[1000005][30],ne[1000005]; void insert(string s){ int u=0; for(char c:s){ int v=c-'a'; if(!ch[u][v])ch[u][v]=++tot; u=ch[u][v]; } cnt[u]++; } void build(){ queueq; for(int i=0;i<26;++i){ if(ch[0][i])q.push(ch[0][i]); } while(!q.empty()){ int u=q.front(); q.pop(); for(int i=0;i<26;++i){ int v=ch[u][i]; if(v)ne[v]=ch[ne[u]][i],q.push(v); else ch[u][i]=ch[ne[u]][i]; } } } int query(string s){ int ans=0; for(int k=0,i=0;s[k];k++){ i=ch[i][s[k]-'a']; for(int j=i;j&&~cnt[j];j=ne[j]){ ans+=cnt[j],cnt[j]=-1; } } return ans; } string t; int main(){ cin>>n; for(int i=1;i<=n;++i){ string s; cin>>s; insert(s); } cin>>t; build(); cout< 本文讲述了如何使用 C++ 完成洛谷的 CF2139B Cake Collection,思路清晰、排版精美 次阅读 [| 次评论](#waline) [CF2139B Cake Collection ↗](https://www.luogu.com.cn/problem/CF2139B "CF2139B Cake Collection") [**安利一下**博客 ↗](https://blog.rusin7.com/ "博客 🥳🎆🎉祝大家 2026 新年快乐")🥳🎆🎉祝大家 2026 新年快乐! [纯享阅读区 ↗](https://www.luogu.com.cn/article/odez28v6 "纯享阅读区") ## 题意分析[#](#题意分析) **核心**:用 mmm 秒去拿 nnn 个烤好的蛋糕,要拿的尽量多。用 [贪心 ↗](https://oi-wiki.org/basic/greedy/ "贪心") 算法。 ## 思路引导[#](#思路引导) 提问 如何保证能选到最好的方案? 成功 对数组 aaa 从大到小进行排序,如果 n≤mn \\le mn≤m,则可以把所有烤箱中的蛋糕都拿一遍,生产蛋糕越多的**越晚拿**,且后面会给出证明:早拿一次再晚拿一次和直接晚拿一次一样,不如直接晚拿一次简单。否则 n\>mn>mn\>m,就直接拿排序后**最好**(aia\_iai​ 较大)的烤箱中的蛋糕,同样,生产蛋糕越多的**越晚拿**。 综上,取个 min⁡{n,m}\\min \\{n,m\\}min{n,m} 即可。 Tip 从大到小进行排序不用手写 `cmp` 了!使用 `greater()` 可以直接大到小进行排序。 示例代码: ``` sort(a+1,a+n+1,greater());//对数组 a 从大到小进行排序 ``` cpp 提问 如何证明早拿一次再晚拿一次同一个烤箱,和直接晚拿一次一样? 成功 **证明**: 设早拿的时间为 p1p\_1p1​,晚拿的时间为 p2p\_2p2​,烤箱每秒生成 aia\_iai​ 个蛋糕,早拿一次再晚拿一次可以拿走 p1×ai+(p2−p1)×ai\=p2×aip\_1 \\times a\_i+(p\_2-p\_1) \\times a\_i=p\_2 \\times a\_ip1​×ai​+(p2​−p1​)×ai​\=p2​×ai​,晚拿一次可以拿走 p2×aip\_2 \\times a\_ip2​×ai​,两式相等,故结论成立。 提问 每拿一次可以获得多少蛋糕? 成功 由于生产蛋糕越多的**越晚拿**,但我们已经从大到小排序了,循环的时间却是从小到大,应该用 m−i+1m-i+1m−i+1 才能让下标 iii 越小,生产蛋糕 aia\_iai​ 越多,时间 m−i+1m-i+1m−i+1 越大。 因此得出 aia\_iai​ 的价值为 (m−i+1)×ai(m-i+1)\\times a\_i(m−i+1)×ai​。 警告 不开 `long long` 见祖宗,不用 `1LL` 乘见祖宗。 ## 完整代码[#](#完整代码) ``` #include using namespace std; long long t,n,m,a[200005],s; int main(){ cin>>t; while(t--){ s=0; cin>>n>>m; for(int i=1;i<=n;i++)cin>>a[i]; sort(a+1,a+n+1,greater()); for(int i=1;i<=min(n,m);i++)s+=1LL*(m-i+1)*a[i]; cout<) / [git](/tags/git) # 对单一仓库配置小号以远程管理小号仓库 > 命令行操作给这个仓库单独设置小号仅本地生效把远程地址绑定到小 次阅读 [| 次评论](#waline) ## 命令行操作[#](#命令行操作) - 给这个仓库单独设置小号(仅本地生效) ``` git config --local user.name "用户名" git config --local user.email "邮箱" ``` bash - 把远程地址绑定到小号仓库 ``` git remote set-url origin https://github.com/用户名/仓库名.git ``` bash - 推送(第一次会让你登录小号) ``` git push -f origin main ``` bash ## 登录时怎么填?[#](#登录时怎么填) 弹出窗口时: **使用 SSH 登录** 在输入框中填入在 [这里 ↗](https://github.com/settings/tokens/new) 创建的 SSH 密钥(权限建议仅 Repo)。 * * * > ## 最终效果(最舒服的状态)[#](#最终效果最舒服的状态) > > - 全局 Git = 大号 > - 其他所有仓库 = 大号 > - 只有特定文件夹 = 小号 {% note blue ‘anzhiyufont anzhiyu-icon-bullhorn’ modern %}永远不用再切换账号{% endnote %} --- ## 在 VPS 上部署洛谷保存站 URL: https://blog.rusin7.com/article/deploy-lg-saver 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) ![在 VPS 上部署洛谷保存站](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) 2026/08/11 8 分钟 [云服务器](/tags/云服务器) / [建站](/tags/建站) / [教程](/tags/教程) # 在 VPS 上部署洛谷保存站 > 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) 次阅读 [| 次评论](#waline) ## 项目地址[#](#项目地址) [Demo ↗](https://luogu.rusin7.com/) [https://luogu.rusin7.com/](https://luogu.rusin7.com/) [ laikit-dev / luogu-saver Waiting for api.github.com... ??? ??? ??? ????? ](https://github.com/laikit-dev/luogu-saver) ## 前置要求[#](#前置要求) 在开始之前,请确保你已具备以下条件: - 有一个邮箱或 Github、Google 账号。 - 有一定的 Linux 终端操作能力和 Web 知识。 - 能支付一个月 333 美元的费用或已经有服务器了。 ## 购买 VPS(如果你有服务器可以忽略)[#](#购买-vps如果你有服务器可以忽略) 进入 [Zeabur 注册 ↗](https://zeabur.cn/zh-CN/login),然后选一种方式注册,进入仪表盘后点击左侧“服务器”,然后点击“创建服务器”,选择“服务器-单机部署”,再选择“从 zeabur 购买服务器”,点击“前往购买”。 ![1](https://image.rusin7.com/file/uvHywUpv.png) 供应商选择 Tencent,方案中区域:`亚洲`,排序:`价格 ↑`,在前 444 个价格为 333 美元的服务器选一个。操作系统选 ZeaburOS,然后前往结账. ![2](https://image.rusin7.com/file/Zw5chk7S.png) 勾选 `我已阅读并同意上述重要事项······`,点击“设置付款方式”,选“充值余额”,然后用支付宝或微信支付充值到账户里。支付后,满屏的烟花会庆祝你的成功,然后你的服务器将会安装一系列自带的 Zeabur 服务。 ![3](https://image.rusin7.com/file/y2hhrecN.png) 到此,服务器就购买成功了! ### SSH 服务器[#](#ssh-服务器) 回到 Zeabur 首页,点击服务器、你的服务器名字进入详细页面,点击服务器运行信息中的 IPv4 旁边的一串 IP 地址复制下来,打开终端,输入以下内容: ``` ssh ubuntu@ ``` bash 如果输出 `ubuntu@'s password:`,那么没有问题,先不要关闭终端。 然后回到 Zeabur 服务器页面,点击上侧的 `SSH`,点击 SSH 密码下面的“···”(**不是“连接”**),此时可能会弹出警告,大致意思是“如果你在 ssh 后一不小心弄坏(`rm -rf`)了服务器,他们无法回复,只能重装系统”,不必理会,直接点“确定放弃权利”,然后点击密码复制到剪贴板,再回到终端,粘贴密码(粘贴时不会有 `*` 等字符出现,属于正常现象),让后 `Enter`,第一次 SSH 有交互式提问,输入 `y` 即可。如果终端输出类似如下,那么就成功了! ``` Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-124-generic x86_64) ··· ``` bash ## 部署保存站[#](#部署保存站) ### 部署基础设施 (数据库、缓存等)[#](#部署基础设施-数据库缓存等) 克隆项目仓库并进入目录: ``` git clone https://github.com/laikit-dev/luogu-saver.git cd luogu-saver ``` bash 编辑 docker-compose.yml 中密码: ``` nano docker-compose.yml ``` bash 用上、下键移动光标找到 `services.db.environment.MARIADB_ROOT_PASSWORD` 并修改为自己的密码,例:`MARIADB_ROOT_PASSWORD: 123456`。再找到 `services.meilisearch.environment.MEILI_MASTER_KEY` 并修改为自己的密码,例:`MEILI_MASTER_KEY: 123456`。然后按 `Ctrl + O , Enter`(字母 `O`,不是 000),最后按 `Ctrl + X` 退出。 然后启动基础设施服务: ``` sudo docker compose up -d ``` bash ### 构建项目[#](#构建项目) #### 升级 Node.js[#](#升级-nodejs) 由于默认 Node.js 版本过低(v18.19.1)而项目要求的 Node.js 版本是 22.18.0 或更高(见 README),Vite 也要求 20.19+ 或 22.12+。需要升级 Node.js。 安装 nvm ``` curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash source ~/.bashrc ``` bash 安装并切换到 Node.js 22 ``` nvm install 22 nvm alias default 22 nvm use 22 ``` bash 验证一下: ``` node -v ``` bash 应该显示 `v22.x.x`。 #### 开始构建[#](#开始构建) ``` npm install npm run build export VITE_API_URL=http://你的域名 # 替换为你的自定义域名 cd ~/luogu-saver/packages/backend npm install --production --ignore-scripts ``` bash #### 安装依赖、创建数据库[#](#安装依赖创建数据库) ``` sudo npm install -g pm2 sudo apt update && sudo apt install nginx -y sudo docker exec -it mariadb-docker-saver mariadb -u root -p ``` bash 然后输入 `docker-compose.yml` 中你设置的第 111 个(MariaDB)的密码(输入时不会有 `*` 等字符出现,属于正常现象)。进入控制台后粘贴以下脚本: ``` CREATE DATABASE luogu_saver CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; EXIT; ``` bash ### 配置后端[#](#配置后端) 编辑 `config.yml`: ``` cd ~/luogu-saver/packages/backend nano config.yml ``` bash 粘贴以下内容,注意修改自己的密码: ``` port: 3000 env: "development" network: timeout: 30000 db: host: "127.0.0.1" port: 3306 user: "root" password: "你的MariaDB密码" database: "luogu_saver" redis: host: "127.0.0.1" port: 6379 password: "" keyPrefix: "" chroma: enable: false ssl: false host: "127.0.0.1" port: 8000 collectionName: "lgs_articles" queue: save: concurrencyLimit: 2 maxRequestToken: 20 regenerationInterval: 1000 maxQueueLength: 1000 ai: concurrencyLimit: 10 maxRequestToken: 50 regenerationInterval: 1000 maxQueueLength: 2000 update: concurrencyLimit: 2 maxRequestToken: 20 regenerationInterval: 1000 maxQueueLength: 1000 llm: providers: [] scenarios: chat: use: "openai" temperature: 0.7 maxTokens: 2048 topP: 1 frequencyPenalty: 0 presencePenalty: 0 stopSequences: [] summary: use: "openai" temperature: 0.7 maxTokens: 1024 embedding: use: "openai" censor: use: "openai" recommendation: anonymous: expireTime: 604800 maxCount: 100 maxHistory: 500 decayFactor: 0.9 relevantThreshold: 0.75 verification: luogu: codeExpireTime: 300 codeLength: 32 judgement: enabled: true intervalMs: 1200000 runOnStartup: true sourceUrl: "https://www.luogu.com.cn/judgement" ``` yaml 启动后端: ``` pm2 start dist/index.js --name luogu-backend ``` bash ### 托管前端[#](#托管前端) #### 配置 Nginx[#](#配置-nginx) 这是最后一步,让前端页面可以通过 HTTP 访问。 ``` sudo nano /etc/nginx/sites-available/default ``` bash 将内容替换为(注意添加你的生产域名在 `server_name`): ``` server { listen 81; server_name _; # 示例:server_name _ example.com; root /home/ubuntu/luogu-saver/packages/frontend/dist; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { rewrite ^/api/(.*) /$1 break; proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } ``` nginx 保存后,测试并启动 Nginx: ``` ssudo chmod o+x /home/ubuntu sudo chmod -R o+rX /home/ubuntu/luogu-saver/packages/frontend/dist sudo nginx -t sudo systemctl restart nginx sudo systemctl enable nginx ``` bash ### 自定义域名[#](#自定义域名) 在你的域名服务商后台,添加一条 A 记录: - 主机记录:`luogu`(取决于你想用哪个子域名) - 记录值:`你的服务器 IP` - TTL:随意 ### 转发端口[#](#转发端口) 现在,我们需要在 Zeabur 上部署一个 Nginx 服务,专门用来转发流量,是可以通过 808080 端口(`https://example.com`)访问(即访问网站时的默认端口,否则只能通过 `https://example.com:81` 访问,不够优雅)。 在仪表盘右上角点“创建项目”新建一个 Zeabur 项目,点击左侧“新建服务”,点击“模板”,输入“Nginx”部署,然后点“设置”,选择“打开配置文件编辑器”,粘贴以下代码: ``` worker_processes 5; error_log stderr; worker_rlimit_nofile 8192; events {} http { default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] $status ' '"$request" $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /dev/stdout main; sendfile on; tcp_nopush on; server_names_hash_bucket_size 128; server { listen 80 default_server; server_name _; location / { proxy_pass http://服务器 IP:81; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } } ``` nginx 然后点击网络-绑定外部域名,添加你的域名 `example.com` 并确认。 然后会自动开始部署,耐心等待一会,当状态变为运行中时,可以打开你的域名,如果没有问题的话。 恭喜你,部署成功了! ## 参考资料[#](#参考资料) --- ## 拯救谷歌和 Github!你的新“自行车” URL: https://blog.rusin7.com/article/devsidecar 快速安装,找到最新版本,安装包选择方式:Windows:De 2026/05/14 1 分钟 [git](/tags/git) # 拯救谷歌和 Github!你的新“自行车” > 快速安装,找到最新版本,安装包选择方式:Windows:De 次阅读 [| 次评论](#waline) 还在为谷歌无法访问而发愁吗?[这个宝藏项目 ↗](https://github.com/docmirror/dev-sidecar)一定要收藏好😍!顺便还能秒开 Github! ## 快速安装[#](#快速安装) [打开 Release ↗](https://github.com/docmirror/dev-sidecar/releases),找到最新版本,安装包选择方式: - **Windows**:DevSidecar-x.x.x-windows-universal.exe - **Mac**: DevSidecar-x.x.x-macos-universal.dmg - **Linux**: - Debian 系等支持 Deb 的:DevSidecar-x.x.x-linux-<架构>.deb - 其他:DevSidecar-x.x.x-linux-<架构>.AppImage 安装可能有点慢,建议以下 4 选 1 加速安装(我的是 2.0.2 Windows 版本,具体链接为 [https://gh-proxy.org/+Github ↗](https://gh-proxy.org/+Github) 原始链接): - [主站,全球加速! ↗](https://gh-proxy.org/https://github.com/docmirror/dev-sidecar/releases/download/v2.0.2/DevSidecar-2.0.2-windows-universal.exe) - [香港国内线路优化 ↗](https://hk.gh-proxy.org/https://github.com/docmirror/dev-sidecar/releases/download/v2.0.2/DevSidecar-2.0.2-windows-universal.exe) - [Fastly CDN ↗](https://cdn.gh-proxy.org/https://github.com/docmirror/dev-sidecar/releases/download/v2.0.2/DevSidecar-2.0.2-windows-universal.exe) - [Edgeone 全球加速 ↗](https://edgeone.gh-proxy.org/https://github.com/docmirror/dev-sidecar/releases/download/v2.0.2/DevSidecar-2.0.2-windows-universal.exe) --- ## 图论之欧拉回路、差分约束——算法笔记 URL: https://blog.rusin7.com/article/euro-circuit-notes 本文讲述了图论之欧拉回路、差分约束的 C++ 代码,并推荐了比赛和题目以便练习。 ![图论之欧拉回路、差分约束——算法笔记](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/04/03 2 分钟 [c++](/tags/c++) # 图论之欧拉回路、差分约束——算法笔记 > 本文讲述了图论之欧拉回路、差分约束的 C++ 代码,并推荐了比赛和题目以便练习。 次阅读 [| 次评论](#waline) # 图论之欧拉回路、差分约束——算法笔记[#](#图论之欧拉回路差分约束算法笔记) [比赛 ↗](https://vjudge.net/contest/767358) ## 欧拉回路[#](#欧拉回路) 无向代码1: ``` void dfs(int x){ while(f[x] using namespace std; int n,m,d[100005],c[100005],f[100005]/*表示遍历到第几个点*/; vectora[100005]; stackst; void dfs(int x){ int l=0; while(f[x]>n>>m; int ind[100005],outd[100005],u,v; for(int i=1;i<=m;++i){ cin>>u>>v; a[u].push_back(v); ind[v]++,outd[u]++; } for(int i=1;i<=n;++i)sort(a[i].begin(),a[i].end()); int x=1,y=0,z=0; for(int i=1;i<=n;++i){ if(ind[i]+1==outd[i])x=i,++y; if(ind[i]!=outd[i])++z; } if(!((y==1&&z==2)||!z)){ cout<<"No"<ans[k.first]+k.second){ ans[i]=min(ans[i],ans[k.first]+k.second),f=1; } } } return f; }; for(int i=0;i using namespace std; int ans[5005]; vector>to[5005]; void Bellman_Ford(int n){ auto relax=[&](){ bool f=0; for(int i=1;i<=n;++i){ for(auto k:to[i]){ if(ans[i]>ans[k.first]+k.second){ ans[i]=min(ans[i],ans[k.first]+k.second),f=1; } } } return f; }; for(int i=0;i>n>>m; fill(ans,ans+n+1,0); for(int i=1;i<=m;++i){ cin>>c1>>c2>>y; to[c1].push_back({c2,y}); } Bellman_Ford(n); return 0; } ``` cpp --- ## 博客迁移分流说明 URL: https://blog.rusin7.com/article/explanation-of-blog-migration 博客迁移分流说明在我的陪伴大家4个月后,由于当时技术较差,不会使用 git 命令行和 node.js,所以不够美观 2026/08/03 1 分钟 [公告](/tags/公告) # 博客迁移分流说明 > 博客迁移分流说明在我的陪伴大家4个月后,由于当时技术较差,不会使用 git 命令行和 node.js,所以不够美观 次阅读 [| 次评论](#waline) 在我的[第 222 个博客 ↗](https://old.blog.rusin7.com)陪伴大家 444 个月后,由于主题过于臃肿,加载太慢,迁移所有文章至此,原博客将归档,望周知。 谢谢你们的支持! --- ## 免费获取二级域名并部署 github 仓库 URL: https://blog.rusin7.com/article/free-domain 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 2026/03/23 5 分钟 [白嫖](/tags/白嫖) / [建站](/tags/建站) / [github](/tags/github) / [cloudflare](/tags/cloudflare) / [教程](/tags/教程) # 免费获取二级域名并部署 github 仓库 > 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 次阅读 [| 次评论](#waline) ## 前提[#](#前提) 拥有一个 [Github ↗](https://github.com) 的账号和博客仓库。 ## 领取域名[#](#领取域名) ### 注册[#](#注册) #### Github[#](#github) 前往 {% btn ‘[https://github.com/signup’,Github,anzhiyufont ↗](https://github.com/signup',Github,anzhiyufont) anzhiyu-icon-circle-arrow-right,purple larger %} 注册账号。 #### DigitalPlat Domains[#](#digitalplat-domains) 前往 {% btn ‘[https://dash.domain.digitalplat.org/signup?ref=uGQR48cE9B’,Digitalplat,anzhiyufont ↗](https://dash.domain.digitalplat.org/signup?ref=uGQR48cE9B',Digitalplat,anzhiyufont) anzhiyu-icon-circle-arrow-right,purple larger %} 注册账号,完整人名、电话号码、完整地址等信息不用填写真实的,可以在 [美国身份生成器 ↗](https://www.meiguodizhi.com/) 生成。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/2.png) 注册完成后会发一封验证到邮箱。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/3.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/4.png) 登录后需要 KYC 验证(使用 Github 账号即可)。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/5.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/6.png) 验证成功后会显示这个页面。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/7.png) ### 获取[#](#获取) 书接上回,点击左侧 注册。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/8.png) {% tip error %}Digitalplat 于 2026/3/20(文章发布约一周后) 左右更新 UI 和页面交互,文章中获取部分截图为旧版,可能无法对应位置,但操作基本相同。{% endtip %} {% tip fa-atom, sync %}UppubDatetime: 本文章已更新至最新。{% endtip %} {% link 旧版存档,点击查看旧版,[https://life.rusin7.com/post/dpdns-org/ ↗](https://life.rusin7.com/post/dpdns-org/) %} {% link DigitalPlat Domains 仪表盘,下滑找到我的域名统计-最大允许域名数,[https://dash.domain.digitalplat.org/dashboard ↗](https://dash.domain.digitalplat.org/dashboard) %} 下滑找到我的域名统计-最大允许域名数,正常是 222 个,如果你开始没按我的教程注册是 111 个。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/9.png) {% note info flat %} 每个账户理论上可以注册 333 个免费的 dpdns.org 域名。 - 第 222 个需要在注册时, Referral code 填 `uGQR48cE9b` 或 `QFFXW3uiRm`,如果按前面我的教程一步步注册,可以默认拥有 222 个,再 star 一下获得第 333 个。 - 第 333 个需要给他们的 Github 项目 star,点击验证通过后就可以,验证不难。 {% endnote %} - 登录 Github。 - {% btn ‘[https://github.com/DigitalPlatDev/FreeDomain’,访问仓库,anzhiyufont ↗](https://github.com/DigitalPlatDev/FreeDomain',%E8%AE%BF%E9%97%AE%E4%BB%93%E5%BA%93,anzhiyufont) anzhiyu-icon-circle-arrow-right %}。 - 点击右上角 ⭐“Star”。 - 点击 {% btn ‘[https://dash.domain.digitalplat.org/auth/kyc/github’,这里,anzhiyufont ↗](https://dash.domain.digitalplat.org/auth/kyc/github',%E8%BF%99%E9%87%8C,anzhiyufont) anzhiyu-icon-circle-arrow-right %}。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/10.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/11.png) [https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/sourcehttps://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/12.png ↗](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/sourcehttps://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/12.png) * * * 点击 {% btn 'https://dash.domain.digitalplat.org/panel/main?page=%2Fpanel%2Fregister',注册,anzhiyufont anzhiyu-icon-circle-arrow-right,pink larger %},填写想注册的域名。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/12.png) 如果被占用,可以换个域名试试,被占用图片: ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/13.png) 红框中的 \*Name Server1,\*Name Server2先填 `1.com` 和 `2.com`,等会儿可以修改。未被占用图片: ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/14.png) 域名注册成功后会显示这个页面。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/15.png) ## 托管到 CF[#](#托管到-cf) ### 登录[#](#登录) 用 Github [登录 Cloudflare ↗](https://dash.cloudflare.com/login)。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772802324633.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772802412422.png) ### 添加[#](#添加) 点击添加站点(Onboard a domain)。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772802648682.png) 选择免费版继续。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772804243558.png) 类型选择 CHAME,名称填写 `@` ,目标填写 Github page 地址(username.github.io,将 username 替换为你的 Github 用户名),点击保存(Save)。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772804929713.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772804934072.png) 保存后效果如下图。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772805054433.png) 点击底部蓝色 继续激活 按钮。 ### 修改 Name Server[#](#修改-name-server) 回到[注册域名的网站 ↗](https://dash.domain.digitalplat.org/domains),点击刚刚的域名,下滑页面,找到原来是 1.com 和 2.com 的 Name server。在 Cloudflare 页面点击 显示名称服务器指令 ( `Show nameserver instructions` ) 依次点击 Click to copy 按钮并依次复制到刚刚的域名的 Name server 1 和 Name server 2,修改后继续在注册域名的网站点击 `更新名称服务器` ( `UppubDatetime nameservers` ),成功后效果如下图。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/16.png) ### 检查[#](#检查) 回到 Cloudflare,点击 `现在就检查名称服务器` ( `Check nameservers now` )。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772848750931.png) 域名注册商可能需要 333 分钟 ∼24\\sim 24∼24 小时来处理 Nameserver 的更新,当你的网站在 Cloudflare 上激活后,你会收到一封邮件通知。 你也可以保留 Cloudflare 页面,当显示如下两图时,说明检查成功了。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772851053998.png) 单个域名概述页面 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772851718121.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772851759034.png) 所有域名管理页面 ## 结语[#](#结语) 可以愉快地享用Cloudflare的服务了! 祝大家打造出品牌化的个人博客,为平凡的生活添彩! --- ## Cyanwind 主题 markdown 语法 URL: https://blog.rusin7.com/article/how-to-use-markdown 学习 Markdown 的基础语法,从入门到精通。 2026/08/28 / Update 2026/08/31 17 分钟 zh [教程](/tags/教程) / [markdown](/tags/markdown) # Cyanwind 主题 markdown 语法 > 学习 Markdown 的基础语法,从入门到精通。 次阅读 [| 次评论](#waline) ## Markdown 是什么[#](#markdown-是什么) [Markdown ↗](https://markdown.com.cn/ "官网") 是一种轻量级标记语言,排版语法简洁,让人们更多地关注内容本身而非排版。它使用易读易写的纯文本格式编写文档,可与HTML混编,可导出 HTML、PDF 以及本身的 .md 格式的文件。因简洁、高效、易读、易写,Markdown被大量使用,如Github、Wikipedia、简书等。 ## Markdown 编辑器[#](#markdown-编辑器) Markdown 入门的最佳方式就是多使用它。由于有大量免费工具的存在,上手 Markdown 是很方便的。比较遗憾的一点是**各平台可能采用不同语言实现的 Markdown 解析引擎**,例如 Gridea 和 Luogu 就不同,而且可能有不同程度的定制与扩展,这导致在不同平台上使用 Markdown 写作时体验并不完全一致。不过幸好对于大家公认的一些标准语法,各家都是支持的。 你甚至都不需要下载任何程序,就可以使用[在线 Markdown 编辑器 ↗](https://markdown.com.cn/editor/)来编写 Markdown。进入其站点就可以开始在左侧窗格中书写了。渲染后的文档在右侧窗格预览。 阅读本指南时,你可以打开[在线 Markdown 编辑器 ↗](https://markdown.com.cn/editor)。这样,你就可以一边学习 Markdown 语法一边练习了。熟悉 Markdown 之后,再选择一个顺手的 Markdown 的应用程序。 ## Markdown 标题语法[#](#markdown-标题语法) Markdown 的标题是在行首插入 111 到 666 个 `#`,`#` 和标题文字之间使用一个或多个空格,对应到标题 111 到 666 级。 警告 标题**不用来**强调,滥用标题可能会让读者感到困惑。 ### 预览[#](#预览) ![预览](https://image.rusin7.com/file/hexo/article/markdown/851kcAXJ.png) ### 源码[#](#源码) ``` # 1级标题 ## 2级标题 ### 3级标题 #### 4级标题 ##### 5级标题 ###### 6级标题 这是正文 ``` markdown ### 可选语法[#](#可选语法) 还可以在文本下方添加任意数量的 `==` 号来标识一级标题,或者 `--` 号来标识二级标题。 > **警告** 如果你想在一句正文后添加分割线,请使用`***`而非`---`避免错误地标识二级标题。 #### 预览[#](#预览-1) ![预览](https://image.rusin7.com/file/hexo/article/markdown/OtaGC9sA.png) #### 源码[#](#源码-1) ``` 1级标题 =============== 2级标题 --------------- ``` markdown ## Markdown 强调语法[#](#markdown-强调语法) 通过将文本设置为粗体、斜体、删除线、高亮来强调其重要性。 ### 预览[#](#预览-2) _单星号斜体_ _单下划线斜体_ **双星号加粗** **双下划线加粗** 删除线 _**混合效果**_ ### 源码[#](#源码-2) ``` *单星号斜体* _单下划线斜体_ **双星号加粗** __双下划线加粗__ ~~删除线~~ ***混合效果*** ``` markdown 如果要在文字前后直接插入普通的星号或底线,可以用反斜线(`\`)(参见下面的[“转义字符”部分](#markdown-%E8%BD%AC%E4%B9%89%E8%AF%AD%E6%B3%95))。 ### 预览[#](#预览-3) 使用反斜线开头的被当做是普通的字符 ### 源码[#](#源码-3) ``` \*使用反斜线开头的\*被当做是普通的字符\* ``` markdown ## Markdown 代码语法[#](#markdown-代码语法) ### 大段代码[#](#大段代码) Markdown 建立代码块的方法:将 `置于这段代码的首行和末行,独立成一行。第一行的` 后面可以加上语言名称,例如 c++、java、c、pascal、markdown、latex 等。 #### 预览[#](#预览-4) ``` #include using namespace std; int main(){ int a, b; cin >> a >> b; cout << a + b << endl; return 0; } ``` c #### 源码[#](#源码-4) ```` ```c++ #include using namespace std; int main(){ int a, b; cin >> a >> b; cout << a + b << endl; return 0; } ```` markdown ```` ### 小段代码 需要引用代码时,如果引用的语句只有一段,不分行,可以用 ` 将语句包起来。 #### 预览 这样 `不分行引用代码` 就行了。 #### 源码 ```markdown 这样 `不分行引用代码` 就行了。 ```` plaintext ## Markdown 引用语法[#](#markdown-引用语法) ### 预览[#](#预览-5) > Markdown 标记区块引用的方法是在行的最前面加 `>`。 > > 也可以只在整个段落的第一行最前面加上 `>`。 > > > 区块引用内部可以嵌套,只要根据层次加上不同数量的 `>` 即可。 > > > > _我是内部嵌套区块,我可以使用其他 Markdown 语法哦。_ > > > > ### 引用区块内可以使用标题语法。[#](#引用区块内可以使用标题语法) > > > > - Yes,可以加入列表. > > - No,可以加入列表. > > > > ``` > > //在引用区块内可以加入代码块 > > import java.net.URL; > > import java.util.Arrays; > > import java.util.Date; > > import java.util.Set; > > ``` > > > > java ### 源码[#](#源码-5) ``` > Markdown 标记区块引用的方法是在行的最前面加 `>`。 > > 也可以只在整个段落的第一行最前面加上 `>`。 > > 区块引用内部可以嵌套,只要根据层次加上不同数量的 `>` 即可。 > > > > *我是内部嵌套区块,我可以使用其他 Markdown 语法哦。* > > > > ### 引用区块内可以使用标题语法。 > > - [x] Yes,可以加入列表. > > - [ ] No,可以加入列表. > > ```java > > //在引用区块内可以加入代码块 > > import java.net.URL; > > import java.util.Arrays; > > import java.util.Date; > > import java.util.Set; > > ``` ``` markdown ## Markdown 列表语法[#](#markdown-列表语法) Markdown 支持有序列表和无序列表以及任务列表。无序列表使用星号、加号或是减号作为列表标记,有序列表则使用数字接着一个英文句点。两种列表方式格式都是:列表标记 + 空格 + 列表项,即列表项目标记通常是放在最左边,也可以缩进最多 333 个空格,项目标记后面则一定要接着至少一个空格或制表符。 列表**可以**嵌套。 ### 无序列表[#](#无序列表) 星号、加号或是减号三种列表方式效果等同。 #### 预览[#](#预览-6) - Red - Green - Blue - Red - Green - Blue - Red - Green - Blue #### 源码[#](#源码-6) ``` * Red * Green * Blue + Red + Green + Blue - Red - Green - Blue ``` markdown ### 有序列表[#](#有序列表) 有序列表则使用数字接着一个英文句点 `.` 或英文括号 `(`,添加带有数字和周期的行项。数字**不必**按数字顺序排列,但列表应从数字 111 开始。 #### 预览[#](#预览-7) 1. First item 2. Second item 3. Third item 4. Fourth item * * * 1. First item 2. Second item 3. Third item 4. Fourth item * * * 1. First item 2. Second item 3. Third item 4. 缩进项 5. 缩进项 6. Fourth item #### 源码[#](#源码-7) ``` 1. First item 2. Second item 3. Third item 4. Fourth item --- 1. First item 1. Second item 1. Third item 1. Fourth item --- 1) First item 3) Second item 8) Third item 1) 缩进项 2) 缩进项 5) Fourth item ``` markdown ### 任务列表[#](#任务列表) 务列表是一种特殊的列表,它可以在列表项前添加复选框,用于表示任务是否完成。任务列表的格式为:- 任务项 或 - x 任务项,其中 表示未完成任务,x 表示已完成任务。 #### 预览[#](#预览-8) - 学习 Markdown 语法 - 完成 Markdown 语法学习 - 编写 Markdown 文档 #### 源码[#](#源码-8) ``` - [ ] 学习 Markdown 语法 - [x] 完成 Markdown 语法学习 - [ ] 编写 Markdown 文档 ``` plaintext ## Markdown 链接语法[#](#markdown-链接语法) 使用链接带给读者更好的网站跳转效果和渲染机制。 ### 美观链接[#](#美观链接) 链接文本放在中括号内,链接地址放在后面的括号中,链接title是当鼠标悬停在链接上时会出现的文字,这个title是可选的,它放在圆括号中链接地址后面,跟链接地址之间以空格分隔。 #### 预览[#](#预览-9) [行内式链接标题(无title) ↗](https://ruying-suixing.github.io/) [行内式链接标题(有title),可将光标移至链接上查看 title 效果。 ↗](https://ruying-suixing.github.io/ "可选标题") \*\*[行内式\*\* _链接_ 标题(含 Markdown 语法) ↗](https://ruying-suixing.github.io/) #### 源码[#](#源码-9) ``` [行内式链接标题(无title)](https://ruying-suixing.github.io/) [行内式链接标题(有title),可将光标移至链接上查看 title 效果。](https://ruying-suixing.github.io/ "可选标题") [**行内式** _链接_ 标题(含 Markdown 语法)](https://ruying-suixing.github.io/ "可选标题") ``` markdown ## Markdown 图片语法[#](#markdown-图片语法) Markdown 使用一种和链接很相似的语法来标记图片。在互联网上发表含有图片的内容时,需要将该图片上传至可公开访问的存储空间内(也就是俗称的图床),可以使用图床上传图片后复制图片引用地址来使用该图片,行内式的图片语法如下: `![图片下方文字](图片相对路径或绝对路径)` `![图片下方文字](图片相对路径或绝对路径 "可选标题")` 详细叙述如下:一个英文感叹号 `!`,接着一个方括号,里面放上图片的替代文字(这些文字将在图片加载失败的时候显示),接着一个普通括号,里面放上图片的网址,最后还可以用引号包住并加上选择性的 title 文字,像链接语法一样。 ### 预览[#](#预览-10) 无title:![我的博客图片](https://cdn.luogu.com.cn/upload/usericon/1620655.png) 有title,可将光标移至图片上查看 title 效果:![我的博客图片](https://cdn.luogu.com.cn/upload/usericon/1620655.png "可选标题") 无用链接,有title,可将光标移至错误文字上查看 title 效果: ![我的博客图片](https://cdn.luogu.com.cn/upload/usericon/9999999.png "可选标题") 图片套链接:![我的博客图片](https://cdn.luogu.com.cn/upload/usericon/1620655.png "可选标题") [↗](https://ruying-suixing.github.io/) ### 源码[#](#源码-10) ``` 无title:![我的博客图片](https://cdn.luogu.com.cn/upload/usericon/1620655.png) 有title,可将光标移至图片上查看 title 效果:![我的博客图片](https://cdn.luogu.com.cn/upload/usericon/1620655.png "可选标题") 无用链接,有title,可将光标移至错误文字上查看 title 效果: ![我的博客图片](https://cdn.luogu.com.cn/upload/usericon/9999999.png "可选标题") 图片套链接:![我的博客图片](https://cdn.luogu.com.cn/upload/usericon/1620655.png "可选标题")[](https://ruying-suixing.github.io/) ``` markdown ## Markdown 转义语法[#](#markdown-转义语法) 要显示原本用于格式化 Markdown 文档的字符,请在字符前面添加反斜杠字符 。 渲染效果如下: Without the backslash, this would be a bullet in an unordered list. ### 可做转义的字符[#](#可做转义的字符) 以下列出的字符都可以通过使用反斜杠字符从而达到转义目的。 | Character | Name | | --- | --- | | | backslash | | | backtick | | | asterisk | | | underscore | | { } | curly braces | | | brackets | | ( ) | parentheses | | # | pound sign | | + | plus sign | | | minus sign (hyphen) | | . | dot | | ! | exclamation mark | ### 预览[#](#预览-11) 反斜线 反引号 星号 底线 } 花括号 \] 方括号 ) 括弧 井字号 加号 减号 英文句点 惊叹号 ### 源码[#](#源码-11) ``` \\ 反斜线 \` 反引号 \* 星号 \_ 底线 \{} 花括号 \[] 方括号 \() 括弧 \# 井字号 \+ 加号 \- 减号 \. 英文句点 \! 惊叹号 ``` markdown ## Markdown 分隔线语法[#](#markdown-分隔线语法) 要创建分隔线,请在单独一行上使用三个或多个星号 (`***`)、破折号 (`---`) 或下划线 (`___`) ,并且不能包含其他内容。 ### 预览[#](#预览-12) 这是第一段内容。 * * * * * * * * * 这是第二段内容。 ### 源码[#](#源码-12) ``` 这是第一段内容。 *** --- _________________ 这是第二段内容。 ``` markdown ## Markdown 表格语法[#](#markdown-表格语法) 使用 `|` 划分单元格,并使用 `:` 与三个及以上的 `-` 在第二行用于调整对齐。 ### 预览[#](#预览-13) | 我是左对齐 | 我是居中对齐 | 我是右侧对齐 | | --- | --- | --- | | 内容 | 内容 | 内容 | ### 源码[#](#源码-13) ``` | 我是左对齐 | 我是居中对齐 | 我是右侧对齐 | |:---|:---:|---:| | 内容 | 内容 | 内容 | ``` markdown **源码中**单元格宽度可以变化,如下所示。呈现的输出将看起来相同。 ### 预览[#](#预览-14) | 我是左对齐 | 我是居中对齐 | 我是右侧对齐 | | --- | --- | --- | | 内容 | 内容 | 内容 | ### 源码[#](#源码-14) ``` | 我是左对齐 | 我是居中对齐 | 我是右侧对齐 | | :--- | :---: | ---: | | 内容 | 内容 | 内容 | ``` markdown 表格行数可以变化,如下所示。 ### 预览[#](#预览-15) | 我是左对齐 | 我是居中对齐 | 我是右侧对齐 | | --- | --- | --- | | 内容 | 内容 | 内容 | | 内容 | 内容 | 内容 | | 内容 | 内容 | 内容 | | 内容 | 内容 | 内容 | | 内容 | 内容 | 内容 | ### 源码[#](#源码-15) ``` | 我是左对齐 | 我是居中对齐 | 我是右侧对齐 | |:---|:---:|---:| | 内容 | 内容 | 内容 | | 内容 | 内容 | 内容 | | 内容 | 内容 | 内容 | | 内容 | 内容 | 内容 | | 内容 | 内容 | 内容 | ``` markdown ## Markdown 注释语法[#](#markdown-注释语法) Markdown 没有内置的注释功能,但可以使用一种非官方的 Hack 方法。 ### 预览[#](#预览-16) 这是可见的段落。 这是另一个可见的段落。 ### 源码[#](#源码-16) ``` 这是可见的段落。 [这是一个隐藏的注释]: # 这是另一个可见的段落。 ``` markdown ## Cyanwind 主题扩展语法[#](#cyanwind-主题扩展语法) Cyanwind 主题集成了很多来自于[洛谷 ↗](https://www.luogu.com.cn/article/70w8j2pj)的扩展语法,供写文章使用。 当然,在 Hexo 中也可以通过修改源码实现,教程详见[在 Hexo 中复现洛谷插件](/article/luogu-plugin-in-hexo)。 Markdown 没有文本对齐的语法,但可以使用本主题自带的扩展语法解决。 ### 预览[#](#预览-17) 居左内容。 居中内容。 居右内容。 ### 源码[#](#源码-17) ``` :::align{left} 居左内容。 ::: :::align{center} 居中内容。 ::: :::align{right} 居右内容。 ::: ``` markdown Markdown 没有折叠框的语法,但也可以使用本主题自带的扩展语法解决。 ### 预览[#](#预览-18) 这是一个提示 我是提示内容。 我是父容器 我是一些文字。 我是子容器 1 我是内容 1。 我是一些文字。 我是子容器 2 我是子容器 3 我是内容 2。 我是一些文字。 ### 源码[#](#源码-18) ``` :::info[这是一个提示] 我是提示内容。 ::: :::::warning[我是父容器] 我是一些文字。 ::::success[我是子容器 1]{open} 我是内容 1。 :::: 我是一些文字。 ::::success[我是子容器 2]{open} :::error[我是子容器 3]{open} 我是内容 2。 ::: :::: 我是一些文字。 ::::: ``` markdown Markdown 没有 Codeforces 风格的引言的语法,但也可以使用本主题自带的扩展语法解决。 ### 预览[#](#预览-19) 大家好啊,我是说的道理。 ——otto ### 源码[#](#源码-19) ``` :::epigraph[——otto] 大家好啊,我是说的道理。 ::: ``` plaintext 尽管支持嵌套,**但请不要滥用**。 --- ## JC 提高班期末测试题解 URL: https://blog.rusin7.com/article/jc-the-end-of-class-test-solution 题目描述雪花图是由两个整数x和y均大于1生成的,生成方式如下 2026/06/06 9 分钟 [题解](/tags/题解) / [比赛](/tags/比赛) # JC 提高班期末测试题解 > 题目描述雪花图是由两个整数x和y均大于1生成的,生成方式如下 次阅读 [| 次评论](#waline) # [T1 雪花图 ↗](https://www.luogu.com.cn/problem/CF1829F)[#](#t1-雪花图) ## 题目描述[#](#题目描述) 雪花图是由两个整数 xxx 和 yyy(均大于 111)生成的,生成方式如下: - 以一个中心顶点开始。 - 将 xxx 个新顶点与该中心顶点相连。 - 对每一个这 xxx 个顶点,各自连接 yyy 个新顶点。 例如,下图是 x\=5x=5x\=5,y\=3y=3y\=3 的雪花图。 ![1](https://cdn.luogu.com.cn/upload/vjudge_pic/CF1829F/8093abf53ab9afd4293f2937f4849e3ca604a47a.png) 上图中的雪花图有一个中心顶点 151515,然后有 x\=5x=5x\=5 个顶点与其相连(333、666、777、888 和 202020),每个顶点又分别连接 y\=3y=3y\=3 个顶点。 给定一个雪花图,请你求出 xxx 和 yyy 的值。 ## 输入格式[#](#输入格式) 第一行包含一个整数 ttt(1≤t≤10001 \\leq t \\leq 10001≤t≤1000),表示测试用例的数量。 每个测试用例的第一行包含两个整数 nnn 和 mmm(2≤n≤2002 \\leq n \\leq 2002≤n≤200;1≤m≤min⁡(1000,n(n−1)2)1 \\leq m \\leq \\min\\left(1000, \\frac{n(n-1)}{2}\\right)1≤m≤min(1000,2n(n−1)​)),分别表示图中的顶点数和边数。 接下来的 mmm 行,每行包含两个整数 uuu 和 vvv(1≤u,v≤n1 \\leq u, v \\leq n1≤u,v≤n,u≠vu \\neq vu\=v),表示一条连接顶点 uuu 和 vvv 的边。图中没有重边和自环。 保证给定的图一定是某组大于 111 的整数 xxx 和 yyy 所对应的雪花图。 ## 输出格式[#](#输出格式) 对于每个测试用例,输出一行,包含两个整数 xxx 和 yyy,用空格分隔,顺序不能颠倒。 ## 输入输出样例 #1[#](#输入输出样例-1) ### 输入 #1[#](#输入-1) ``` 3 21 20 21 20 5 20 13 20 1 3 11 3 10 3 4 8 19 8 14 8 9 7 12 7 17 7 18 6 16 6 2 6 6 15 7 15 8 15 20 15 3 15 7 6 1 2 1 3 2 4 2 5 3 6 3 7 9 8 9 3 3 6 6 2 2 1 5 2 2 7 4 3 3 8 ``` plaintext ### 输出 #1[#](#输出-1) ``` 5 3 2 2 2 3 ``` plaintext ## 说明/提示[#](#说明提示) 第一个测试用例如题面所示。注意输出 3 53\\ 53 5 是错误的,因为 xxx 应该在 yyy 之前输出。 ``` #include using namespace std; int t,n,m,cnt[205],mx,ends1[205],u[1005],v[1005]; int check(int x){ for(int i=1;i<=m;++i){ if((u[i]==x&&ends1[v[i]]==1)||(v[i]==x&&ends1[u[i]]==1)){ return 0; } } return 1; } int main(){ cin>>t; while(t--){ int x=0,y=0; cin>>n>>m; memset(ends1,0,sizeof ends1),memset(cnt,0,sizeof cnt),mx=0; for(int i=1;i<=m;++i){ cin>>u[i]>>v[i]; cnt[u[i]]++,cnt[v[i]]++; mx=max({u[i],v[i],mx}); } for(int i=1;i<=mx;++i){ if(cnt[i]==1){ ends1[i]=1; y++; } } for(int j=1;j<=n;++j){ if(ends1[j]!=1&&check(j)){ x=cnt[j]; }else if(ends1[j]!=1&&check(j)){ x=cnt[j]; } } cout< 前景介绍使用方法创建JS文件 次阅读 [| 次评论](#waline) ## 前景介绍[#](#前景介绍) 背景 基于{% btn ‘[https://blog.bsgun.cn/posts/ef58a648/‘,梦爱吃鱼的教程 ↗](https://blog.bsgun.cn/posts/ef58a648/',%E6%A2%A6%E7%88%B1%E5%90%83%E9%B1%BC%E7%9A%84%E6%95%99%E7%A8%8B) %}进行修改,主要改进是**更换 API 地址**,因为[原 API ↗](https://api.nsmao.net/) 已经失效。 ## 使用方法[#](#使用方法) ### 创建 JS 文件[#](#创建-js-文件) 在博客主题目录的 js 文件夹(~\\themes\\anzhiyu\\source\\js)下创建 welcome.js 文件(也可以在source文件夹下另外新建文件夹)。 ### 配置经纬度[#](#配置经纬度) {% btn ‘[https://uapis.cn/api/v1/network/myip?source=commercial’,点击这里 ↗](https://uapis.cn/api/v1/network/myip?source=commercial',%E7%82%B9%E5%87%BB%E8%BF%99%E9%87%8C) %},找到 ``` "latitude": xxx,"longitude": xxx, ``` plaintext 复制对应的经度(lng)和纬度(lat)值。 * * * 将以下内容复制到 `welcome.js` 中,并修改文件顶部配置信息 代码 ``` window.IP_CONFIG = { BLOG_LOCATION: { lng: 121.4, // 博主经度 lat: 29.9, // 博主纬度 }, CACHE_DURATION: 1000 * 60 * 60, // 缓存1小时 HOME_PAGE_ONLY: true, // 是否只在首页显示 }; // 添加样式 const addStyles = () => { const style = document.createElement('style'); style.textContent = ` #welcome-info { user-select: none; display: flex; justify-content: center; align-items: center; height: 212px; padding: 10px; margin-top: 5px; border-radius: 12px; background-color: var(--anzhiyu-background); outline: 1px solid var(--anzhiyu-card-border); } .loading-spinner { width: 50px; height: 50px; border: 3px solid rgba(0, 0, 0, 0.1); border-radius: 50%; border-top: 3px solid var(--anzhiyu-main); animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .ip-address { filter: blur(5px); transition: filter 0.3s ease; } .ip-address:hover { filter: blur(0); } .error-message { color: #ff6565; display: flex; flex-direction: column; justify-content: center; align-items: center; } .error-message p, .permission-dialog p { margin: 0; } .error-icon { font-size: 3rem; } #retry-button { margin: 0 5px; color: var(--anzhiyu-main); transition: transform 0.3s ease; cursor: pointer; } #retry-button:hover { transform: rotate(180deg); } `; document.head.appendChild(style); }; // 获取欢迎信息元素 const getWelcomeInfoElement = () => document.querySelector('#welcome-info'); // 显示加载动画 const showLoadingSpinner = () => { const welcomeInfoElement = getWelcomeInfoElement(); if (!welcomeInfoElement) return; welcomeInfoElement.innerHTML = '
'; }; // 显示错误信息 const showErrorMessage = (message = '抱歉,无法获取信息') => { const welcomeInfoElement = getWelcomeInfoElement(); if (!welcomeInfoElement) return; welcomeInfoElement.innerHTML = `
😕

${message}

请重试或检查网络连接

`; document.getElementById('retry-button').addEventListener('click', fetchIpInfo); }; // 缓存相关 const IP_CACHE_KEY = 'ip_info_cache'; const getIpInfoFromCache = () => { const cached = localStorage.getItem(IP_CACHE_KEY); if (!cached) return null; const { data, timestamp } = JSON.parse(cached); if (publishDate.now() - timestamp > IP_CONFIG.CACHE_DURATION) { localStorage.removeItem(IP_CACHE_KEY); return null; } return data; }; const setIpInfoCache = (data) => { localStorage.setItem(IP_CACHE_KEY, JSON.stringify({ data, timestamp: publishDate.now() })); }; // 计算距离 const calculateDistance = (lng, lat) => { const R = 6371; // 地球半径(km) const rad = Math.PI / 180; const dLat = (lat - IP_CONFIG.BLOG_LOCATION.lat) * rad; const dLon = (lng - IP_CONFIG.BLOG_LOCATION.lng) * rad; const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(IP_CONFIG.BLOG_LOCATION.lat * rad) * Math.cos(lat * rad) * Math.sin(dLon / 2) * Math.sin(dLon / 2); return Math.round(R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))); }; // 格式化IP显示 const formatIpDisplay = (ip) => { if (!ip) return "未知IP"; return ip.includes(":") ? "IPv6地址" : ip; }; // 格式化位置 const formatLocation = (region) => { if (!region) return '神秘地区'; return region.replace(/\s+/g, " "); }; // 时段问候 const getTimeGreeting = () => { const hour = new publishDate().getHours(); if (hour < 11) return "早上好🌤️,一日之计在于晨"; if (hour < 13) return "中午好☀️,记得午休喔~"; if (hour < 17) return "下午好🕞,饮茶先啦!"; if (hour < 19) return "即将下班🚶‍♂️,记得按时吃饭~"; return "晚上好🌙,夜生活嗨起来!"; }; // ====================== 终极修复:适配 浙江、江苏 这种简写 ====================== const getGreeting = (region) => { if (!region) return "带我去你的城市逛逛吧!"; const parts = region.trim().split(/\s+/).filter(Boolean); const province = parts[1] || ""; const city = parts[2] || ""; if (city === "南京") return "六朝古都,风华依旧"; if (city === "苏州") return "上有天堂,下有苏杭"; if (city === "杭州") return "东风渐绿西湖柳,雁已还人未南归"; if (city === "郑州") return "豫州之域,天地之中"; if (city === "洛阳") return "洛阳城里见秋风,欲作家书意万重"; if (city === "开封") return "包公那叫一个铁面无私,严惩贪官污吏"; if (city === "宁波") return "海上丝路的起点,和我一个城市。"; if (city === "西安") return "十三朝古都,长治久安!"; // 省份匹配(简写版) if (province === "北京") return "北京欢迎你~~~"; if (province === "天津") return "讲段相声吧"; if (province === "河北") return "山势巍巍成壁垒,天下雄关"; if (province === "山西") return "展开坐具长三尺,已占山河五百余"; if (province === "内蒙古") return "天苍苍,野茫茫,风吹草低见牛羊"; if (province === "辽宁") return "我想吃烤鸡架!"; if (province === "吉林") return "状元阁就是东北烧烤之王"; if (province === "黑龙江") return "很喜欢哈尔滨大剧院"; if (province === "上海") return "众所周知,中国只有两个城市"; if (province === "江苏") return "散装是必须要散装的"; if (province === "浙江") return "望海楼明照曙霞,闲塘十里尽梅花"; if (province === "河南") return "可否带我品尝河南烩面啦?"; return "欢迎来到我的博客!"; }; // ============================================================================== // 生成欢迎信息 const generateWelcomeMessage = (region, dist, ipDisplay) => { const location = formatLocation(region); const timeGreet = getTimeGreeting(); const cityGreet = getGreeting(region); return ` 欢迎来自 ${location} 的小友💖
你当前距博主约 ${dist} 公里!
你的IP地址:${ipDisplay}
${timeGreet}
Tip:${cityGreet}🍂 `; }; const showWelcome = (data) => { if (!data || !data.ip) return showErrorMessage(); const welcomeInfo = getWelcomeInfoElement(); if (!welcomeInfo) return; const dist = calculateDistance(data.longitude, data.latitude); const ipDisplay = formatIpDisplay(data.ip); welcomeInfo.style.display = 'block'; welcomeInfo.style.height = 'auto'; welcomeInfo.innerHTML = generateWelcomeMessage(data.region, dist, ipDisplay); }; // 从uapis.cn获取IP信息 const fetchIpData = async () => { const response = await fetch('https://uapis.cn/api/v1/network/myip?source=commercial'); if (!response.ok) throw new Error('API请求失败'); const result = await response.json(); return result; }; // 获取IP信息主函数 const fetchIpInfo = async () => { showLoadingSpinner(); const cachedData = getIpInfoFromCache(); if (cachedData) { showWelcome(cachedData); return; } try { const data = await fetchIpData(); setIpInfoCache(data); showWelcome(data); } catch (error) { console.error('获取IP信息失败:', error); showErrorMessage('获取IP信息失败,请重试'); } }; const isHomePage = () => { return window.location.pathname === '/' || window.location.pathname === '/index.html'; }; // 插入组件 const insertAnnouncementComponent = () => { const announcementCards = document.querySelectorAll('.card-widget.card-announcement'); if (!announcementCards.length) return; if (IP_CONFIG.HOME_PAGE_ONLY && !isHomePage()) { announcementCards.forEach(card => card.remove()); return; } if (!document.querySelector('#welcome-info')) return; fetchIpInfo(); }; document.addEventListener('DOMContentLoaded', () => { addStyles(); insertAnnouncementComponent(); document.addEventListener('pjax:complete', insertAnnouncementComponent); }); ``` javascript ## 插入 JS 文件[#](#插入-js-文件) 在 `_config.anzhiyu.yml` (或其他主题)主题配置文件下 `inject` 配置项中的 `bottom` 引入 `welcome.js`。 ``` - ``` yaml {% tip info %}图片内容仅供参考,具体根据实际情况修改。{% endtip %} ![截屏](/img/2026/2780309151/1.png) ## 配置内容[#](#配置内容) 确认 `_config.anzhiyu.yml` (或其他主题)主题配置文件下 `aside` 配置项中的 `card_announcement` 是否开启,配置参考: ``` card_announcement: enable: true # 必须开启 content: ···(省略)
# 必须项 ``` yaml ![截屏](/img/2026/2780309151/2.png) * * * {% folding yellow, 注意事项 %} - 确保API密钥正确填写,正确设置白名单 - 经纬度没必要填写详细,为了自身隐私安全 - 选择器可以根据你的主题实际情况修改 {% endfolding %} ## 常见问题[#](#常见问题) **Q**: 为什么显示”无法获取信息”? **A**: 可能是 API 炸了,检查配置并重试。实在不行联系我更新文章。 **Q**: 距离显示不准确? **A**: 正常现象,计算有无法避免的误差,大概就行了。 --- ## 洛谷网校 CSP 初赛笔记 URL: https://blog.rusin7.com/article/luogu-class-csp-j-note 笔记 2026/07/22 2 分钟 [c++](/tags/c++) # 洛谷网校 CSP 初赛笔记 > 笔记 次阅读 [| 次评论](#waline) ## 位运算[#](#位运算) - `&` 如果 x,yx,yx,y 的对应位都为 111,则结果为 111,否则结果为 000。 - `|` 如果 x,yx,yx,y 的对应位都为 000,则结果为 000,否则结果为 111。 - `^` 如果 x,yx,yx,y 的对应位不同,则结果为 111,否则结果为 000。 - `<<` xxx 左移 yyy 位,高位删除,如:(1010)2<<2\=1000(1010)\_{2}\\texttt{<<}2=1000(1010)2​<<2\=1000; - `>>` xxx 右移 yyy 位,低位删除,如:(1010)2\>>2\=0010(1010)\_{2}\\texttt{>>}2=0010(1010)2​\>>2\=0010; ### 应用[#](#应用) ``` n^=1<>x)&1;//获得n的第x位 ``` cpp ### 优先级表[#](#优先级表) `~`\>`<<`和`>>`\>`&`\>`^`\>`|`,同级运算从左向右。 如图,是所有运算的优先级表: ![优先级表](https://image.rusin7.com/file/81VTdvyM.png) ## ASCLL 码[#](#ascll-码) - 0∼90 \\sim 90∼9 : 48∼5748 \\sim 5748∼57 - `A` ∼\\sim∼ `Z`: 65∼9065 \\sim 9065∼90 - `a` ∼\\sim∼ `a`: 97∼12297 \\sim 12297∼122 详情 以数字 0∼90 \\sim 90∼9 开头的都是数字,例如:0x3f3f3f\\texttt{0x3f3f3f}0x3f3f3f --- ## 在 Hexo 中复现洛谷插件 URL: https://blog.rusin7.com/article/luogu-plugin-in-hexo 前言OIer都知道,洛谷中有个,非常好用,效果如下:succ 2026/06/07 13 分钟 [hexo](/tags/hexo) / [安知鱼美化](/tags/安知鱼美化) # 在 Hexo 中复现洛谷插件 > 前言OIer都知道,洛谷中有个,非常好用,效果如下:succ 次阅读 [| 次评论](#waline) ## 前言[#](#前言) OIer 都知道,洛谷中有个 [Markdown 插件 ↗](https://www.luogu.com.cn/article/70w8j2pj "插件 README"),非常好用,效果如下: 这是一个提示 我是提示内容。 我是父容器 我是一些文字。 我是子容器 1 我是内容 1。 我是一些文字。 我是子容器 2 我是子容器 3 我是内容 2。 我是一些文字。 大家好啊,我是说的道理。 ——otto 居左内容。 居中内容。 居右内容。 源码: ``` :::info[这是一个提示] 我是提示内容。 ::: :::::warning[我是父容器] 我是一些文字。 ::::success[我是子容器 1]{open} 我是内容 1。 :::: 我是一些文字。 ::::success[我是子容器 2]{open} :::error[我是子容器 3]{open} 我是内容 2。 ::: :::: 我是一些文字。 ::::: :::epigraph[——otto] 大家好啊,我是说的道理。 ::: :::align{left} 居左内容。 ::: :::align{center} 居中内容。 ::: :::align{right} 居右内容。 ::: ``` markdown 还有更多…… 尽管 [安知鱼主题 ↗](https://docs.anheyu.com) 自带很多 [标签外挂 ↗](https://hexo.anheyu.com/posts/d50a.html),但仍然无法满足复制洛谷文章到博客编写习惯性的需求,于是,我**全网首发**了在 Hexo 中使用洛谷 Md 插件教程。 闲话 由于不良习惯,我的所有 Markdown 文章编写均遵循洛谷的 [专栏全站推荐规范 ↗](https://help.luogu.com.cn/rules/academic/article-standard)、[洛谷主题库题解规范 ↗](https://help.luogu.com.cn/rules/academic/solution-standard)和[如何用 Markdown 和 LaTeX 写一篇排版整齐的题解? ↗](https://help.luogu.com.cn/rules/academic/guide/solution) ## 方法[#](#方法) 知其然,知其所以然 用 Javasript 自定义 Hexo 的 markdown 解析,用正则匹配把标识等进行匹配,转换为 Html,最后由 Css 完成样式。 ## 实现[#](#实现) 详情 本教程以 anzhiyu 主题为例,其他主题亦可,视情况更改 Css 文件目录和引用方式,参见你的博客主题的文档_以后可能会更新_下这篇文章,搞个多主题支持。 首先,在博客中新建 Css (`~/themes/···(主题名称)/source/css/custom_marked.css`)粘贴以下代码并引入(Anzhiyu 主题可以在 config.yml 中的 Inject.head 配置项中引入)。 ``` .align-left { text-align: left !important; } .align-center { text-align: center !important; } .align-right { text-align: right !important; } .epigraph { width: 40%; margin-left: 60%; } .epigraph > :last-child { margin-top: 0; border-top: 1px solid #888; text-align: right; } summary { list-style: none; -webkit-user-select: none; user-select: none; outline: 0; margin: 0; position: relative; padding-left: 24px; font-weight: 700; list-style: none; display: list-item; min-height: 1em; } .foldable { padding: 0.5em 1em; margin: 1em 0 1em 0.2em; border-left-width: 5px; border-left-style: solid; overflow: hidden; } .foldable.info { border-left-color: rgb(52, 152, 219); } .foldable.warning { border-left-color: rgb(255, 193, 22); } .foldable.success { border-left-color: rgb(82, 196, 26); } .foldable.error { border-left-color: rgb(231, 76, 60); } .foldable.bug { border-left-color: rgb(231, 76, 60); } .foldable.flask { border-left-color: rgb(155, 89, 182); } details.info > summary { color: rgb(52, 152, 219); } details.warning > summary { color: rgb(255, 193, 22); } details.success > summary { color: rgb(82, 196, 26); } details.error > summary { color: rgb(231, 76, 60); } details.bug > summary { color: rgb(231, 76, 60); } details.flask > summary { color: rgb(155, 89, 182); } details.info > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } details.success > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } details.warning > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } details.error > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } details.bug > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } details.flask > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } summary::before { content: ""; background-color: currentcolor; -webkit-mask-size: contain; mask-size: contain; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; margin-right: 8px; } summary:after { content: ""; background-color: currentcolor; -webkit-mask-size: contain; mask-size: contain; mask-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20256%20512%22%3E%3Cpath%20d%3D%22M246.6%20278.6c12.5-12.5%2012.5-32.8%200-45.3l-128-128c-9.2-9.2-22.9-11.9-34.9-6.9s-19.8%2016.6-19.8%2029.6l0%20256c0%2012.9%207.8%2024.6%2019.8%2029.6s25.7%202.2%2034.9-6.9l128-128z%22%2F%3E%3C%2Fsvg%3E"); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; position: absolute; right: 0; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; transition: transform 0.2s ease; } details[open] > summary::after { transform: translateY(-50%) rotate(90deg); } pre code.hljs { display: block; overflow-x: auto; padding: 1em; } code.hljs { padding: 3px 5px; } code[class*="language-"], pre { background: #fefefe; color: #383a42; font-family: Fira Code, Fira Mono, Menlo, Consolas, DejaVu Sans Mono, monospace; direction: ltr; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; line-height: 1.5; -moz-tab-size: 2; -o-tab-size: 2; tab-size: 2; -webkit-hyphens: none; -moz-hyphens: none; -ms-hyphens: none; hyphens: none; } code[class*="language-"]::-moz-selection, code[class*="language-"] *::-moz-selection, pre *::-moz-selection { background: #e5e5e6; color: inherit; } code[class*="language-"]::selection, code[class*="language-"] *::selection, pre *::selection { background: #e5e5e6; color: inherit; } pre { padding: 1em; margin: 0.5em 0; overflow: auto; border-radius: 0.3em; } :not(pre) > code[class*="language-"] { padding: 0.2em 0.3em; border-radius: 0.3em; white-space: normal; } .copy-button[data-v-a7061ca4] { position: absolute; top: 0.5em; right: 0.5em; padding: 0.6em; display: flex; align-items: center; justify-content: center; transition: 0.2s ease-in-out opacity, 0.2s ease-in-out color, 0.2s ease-in-out background-color; opacity: 0; background-color: transparent; border: none; border-radius: 4px; cursor: pointer; color: #555; } .code-container { margin: 1rem 0; position: relative; border-radius: 0.3em; } .code-container:hover > .copy-button { opacity: 1; } .code-container:hover > .copy-button:hover { background-color: #ddd; } h1 { font-size: 2em; margin: 0.67em 0; } h1 { margin: 1.5rem 0 1rem; font-size: 2em; padding-bottom: 0.1em; border-bottom: solid 1px #d8d8d8; } h2 { margin: 1.2rem 0 1rem; font-size: 1.5em; padding-bottom: 0.1em; border-bottom: solid 1px #d8d8d8; } h3 { margin: 1.2rem 0 1rem; font-size: 1.2em; } h4 { margin: 1rem 0; font-size: 1.1em; } h5 { margin: 1rem 0; font-size: 1em; } h6 { margin: 1rem 0; font-size: 1em; color: #666; } img { max-width: 100%; } ul, ol { padding-left: 2em; } li + li { margin-top: 0.2em; } li.task-list-item { position: relative; list-style-type: none; } li.task-list-item > input:first-child { position: absolute; left: -1.5em; top: 55%; transform: translateY(-50%); padding: 0; margin: 0; } hr { margin: 1em 0; height: 0; border: none; border-bottom: solid 1px #eee; } a { text-decoration: none; transition: filter 0.1s ease; color: rgb(var(--lcolor--link, 52, 152, 219)); cursor: pointer; } table { border-collapse: collapse; border-spacing: 0; display: block; width: 100%; overflow: auto; word-break: keep-all; margin: 10px; font-variant-numeric: tabular-nums; } th, td { border: 1px solid #ddd; padding: 6px 13px; } blockquote { padding: 10px 20px; margin: 0 0 20px; border-left: 5px solid #eee; } a { background-color: transparent; } ``` css 然后直接在 `~/themes/···(主题名称)/scripts` 中新建 custom\_marked.js(也可以是别的名字),粘贴以下代码即可,**不用引入**。 ``` const allowedFoldableTypes = new Set(['info', 'warning', 'success', 'error', 'bug', 'flask']); function renderMarkdown(content) { return hexo.render.renderSync({ text: content.trim(), engine: 'markdown' }); } function renderCustomBlock(blockType, title, opt, body) { const type = blockType.toLowerCase(); const content = renderMarkdown(body.trim()); if (type === 'align') { const dir = title ? title.trim() : 'left'; return `\n
\n${content}\n
\n`; } if (type === 'epigraph') { const author = title ? `

${title}

` : ''; return `\n
\n${content}${author}\n
\n`; } if (allowedFoldableTypes.has(type)) { const openAttr = opt && opt.includes('open') ? ' open' : ''; const summary = title ? title.trim() : '详情'; return `\n
\n ${summary}\n
\n${content}\n
\n
\n`; } return null; } function parseCustomBlocks(content) { const lines = content.split(/\r?\n/); const root = { type: 'root', children: [] }; const stack = [root]; let codeFence = null; const openRule = /^\s*(:{3,})([a-zA-Z]\w*)(?:\s*\[([^\]]*)\])?(?:\s*\{([^}]*)\})?\s*$/; const closeRule = /^\s*(:{3,})\s*$/; for (const line of lines) { const fenceMatch = line.match(/^\s*(`{3,}|~{3,})/); if (fenceMatch) { const fence = fenceMatch[1]; if (!codeFence) { codeFence = fence; } else if (codeFence === fence) { codeFence = null; } stack[stack.length - 1].children.push({ type: 'text', value: line }); continue; } if (codeFence) { stack[stack.length - 1].children.push({ type: 'text', value: line }); continue; } const openMatch = line.match(openRule); if (openMatch) { const level = openMatch[1].length; const blockType = openMatch[2].toLowerCase(); const title = openMatch[3] || ''; const opt = openMatch[4] || ''; const node = { type: 'block', level, blockType, title, opt, children: [] }; stack[stack.length - 1].children.push(node); stack.push(node); continue; } const closeMatch = line.match(closeRule); if (closeMatch) { const level = closeMatch[1].length; if (stack.length > 1 && stack[stack.length - 1].level === level) { stack.pop(); continue; } } stack[stack.length - 1].children.push({ type: 'text', value: line }); } return renderNode(root); } function renderNode(node) { if (node.type === 'root') { return node.children.map(renderNode).join('\n'); } if (node.type === 'text') { return node.value; } if (node.type === 'block') { const inner = node.children.map(renderNode).join('\n'); const customHtml = renderCustomBlock(node.blockType, node.title, node.opt, inner); if (customHtml !== null) { return customHtml; } const start = `${':'.repeat(node.level)}${node.blockType}${node.title ? `[${node.title}]` : ''}${node.opt ? `{${node.opt}}` : ''}`; const end = ':'.repeat(node.level); return `${start}\n${inner}\n${end}`; } return ''; } hexo.extend.filter.register('before_post_render', data => { if (typeof data.content !== 'string') return data; hexo.log.debug('custom_marked before_post_render', data.source || data.path || data.title || 'unknown'); data.content = parseCustomBlocks(data.content); return data; }); ``` javascript 为什么不用引入? 与前面引入的 Css 不同的是,任意主题的目录 `~/themes/···(主题名称)/scripts` 功能都都一样,Hexo 解析时都会运行改此目录下的**所有** Javascript 文件。 可能的错误 一不小心放到了 `~/themes/anzhiyu/source/js/custom_marked.js` 里。唐 ## 完结[#](#完结) ``` hexo new "plugin-test" hexo cl&&hexo g&&hexo s ``` bash 赶紧在文章里尝试并体验一下吧!是不是很好用?如果有什么建议,可以在[评论区](#post-comment)告诉我哦! --- ## MDX 组件使用:User & Advanced URL: https://blog.rusin7.com/article/mdx-components 文章内组件(Aside/Tabs 等)与高级组件(LinkPreview/GithubCard 等)的使用方式。 2026/01/11 / Update 2026/01/11 1 分钟 zh [markdown](/tags/markdown) # MDX 组件使用:User & Advanced > 文章内组件(Aside/Tabs 等)与高级组件(LinkPreview/GithubCard 等)的使用方式。 次阅读 [| 次评论](#waline) ## 1\. 必须使用 MDX[#](#1-必须使用-mdx) `.md` 文章无法 `import` 组件;请使用 `.mdx`(如 `src/content/blogs//index.mdx`)。 ## 2\. User 组件示例[#](#2-user-组件示例) - [A](#tab-panel-0) - [B](#tab-panel-1) A 面板内容 B 面板内容 隐藏内容写在这里。 ## 3\. Advanced 组件示例[#](#3-advanced-组件示例) ### GitHub 卡片[#](#github-卡片) [ rusin-dev / astro-theme-cyanwind Waiting for api.github.com... ??? ??? ??? ????? ](https://github.com/rusin-dev/astro-theme-cyanwind) ### 链接预览[#](#链接预览) ![Astro - Build the web you want.](https://astro.build/og/astro.jpg)[ Astro builds fast content sites, powerful web applications, dynamic server APIs, and everything in-between. (astro.build) ](https://astro.build/) ### 二维码[#](#二维码) ### 图片组(等高拼图)[#](#图片组等高拼图) ![Image A](https://picr2.axi404.top/1767811093734_image.webp) ![Image B](https://picr2.axi404.top/1767811093734_image.webp) ### 内嵌视频[#](#内嵌视频) --- ## 笔记——树形动态规划 URL: https://blog.rusin7.com/article/notes-of-dp-on-trees 若如图所示,当前dfs至点u,则转移方程得 2026/06/07 2 分钟 [笔记](/tags/笔记) / [c++](/tags/c++) # 笔记——树形动态规划 > 若如图所示,当前dfs至点u,则转移方程得 次阅读 [| 次评论](#waline) 详情 **设计状态**:用 dpu,0/1dp\_{u,0/1}dpu,0/1​ 表示以 uuu 为根的子树的最大快乐指数。 **答案**:max⁡{dproot,1,dproot,0}\\max\\{dp\_{root,1},dp\_{root,0}\\}max{dproot,1​,dproot,0​}。 ## [P1352 没有上司的舞会 ↗](https://www.luogu.com.cn/problem/P1352)[#](#p1352-没有上司的舞会) 若如图所示,当前 dfs 至点 uuu,则转移方程如下: dpu,0←dpu,0+max⁡(dpv,0,dpv,1)dp\_{u,0}\\leftarrow dp\_{u,0}+\\max(dp\_{v,0},dp\_{v,1})dpu,0​←dpu,0​+max(dpv,0​,dpv,1​) dpu,1←dpu,1+dpv,0dp\_{u,1}\\leftarrow dp\_{u,1}+dp\_{v,0}dpu,1​←dpu,1​+dpv,0​ ![1](https://cdn.luogu.com.cn/upload/image_hosting/dizzn16u.png) 所以可以写出以下代码: ``` #include using namespace std; int n,r[6005],in[6005],rt,dp[6005][2]; vectorg[6005]; void dfs(int u){ for(int v:g[u]){ dfs(v); dp[u][0]+=max(dp[v][0],dp[v][1]); dp[u][1]+=dp[v][0]; } dp[u][1]+=r[u]; } int main(){ cin>>n; for(int i=1;i<=n;++i){ cin>>r[i]; } for(int i=1;i>u>>v; g[v].push_back(u); in[u]=1; } for(int i=1;i<=n;++i){ if(!in[i]){ rt=i; break; } } dfs(rt); cout< using namespace std; int n,in[5005],dp[5005][2],rt; vectorg[5005]; void dfs(int u){ dp[u][0]=0; dp[u][1]=1; for(int v:g[u]){ dfs(v); dp[u][0]+=dp[v][1]; dp[u][1]+=min(dp[v][0],dp[v][1]); } } int main(){ cin>>n; for(int i=1;i<=n;++i){ int u,k,v; cin>>u>>k; u++; for(int j=1;j<=k;++j){ cin>>v; v++; g[u].push_back(v); in[v]=1; } } for(int i=1;i<=n;++i){ if(!in[i]){ rt=i; break; } } dfs(rt); cout< using namespace std; int n,a[16005],dp[16005],ans=INT_MIN; vectorg[16005]; void dfs(int u,int fa){ dp[u]=a[u]; for(int v:g[u]){ if(v!=fa){ dfs(v,u); dp[u]+=max(0,dp[v]); } } } int main(){ cin>>n; for(int i=1;i<=n;++i)cin>>a[i]; for(int i=1;i>u>>v; g[u].push_back(v); g[v].push_back(u); } dfs(1,0); for(int i=1;i<=n;++i){ ans=max(dp[i],ans); } cout< 本文讲述了如何使用 C++ 完成洛谷的 P13361 \[GCJ 2011 Qualification\] Bot Trust」水落溪流浅浅,思路清晰、排版精美 次阅读 [| 次评论](#waline) 本题解被打回无法重新提交嘤嘤嘤 ## 题意理解[#](#题意理解) ### 形式化翻译[#](#形式化翻译) 题目翻译有点难懂(其实是本蒟蒻懒得看),让本蒟蒻来形式化一下: 对于每组测试用例,有 nnn 个执行任务的机器人和对应的按钮, 222 个机器人需**依次**按下自己对应的按钮,求计算 222 个机器人按完按钮所需的最少时间。 ### 注意事项[#](#注意事项) - 必须严格按照给定顺序操作,后一个按钮的操作必须在前一个完成后才能开始。 - 机器人可同时移动但**不能同时执行**按键操作。 ## 解题思路[#](#解题思路) ### 状态跟踪[#](#状态跟踪) 需使用记录两个机器人的当前位置 posoposoposo 和 posbposbposb ( posoposoposo 对应`Orange`, posbposbposb 对应`Blue`)和各自上次操作完成的时间 timeotimeotimeo 和 timebtimebtimeb ,以及整个流程的总时间 sss 。 对于每组测试用例,**千万不要忘记**对 posoposoposo 、 posbposbposb 、 timeotimeotimeo 和 timebtimebtimeb 进行**初始化**! ### 操作逻辑[#](#操作逻辑) - 对每个命令,先确定执行的机器人(判断输入为`O`或`B`)。 - 计算从到达目标位置的时间 ∣ai−poso/posb∣×1|a\_i-poso/posb| \\times1∣ai​−poso/posb∣×1 。 - 确定实际完成时间:取到达时间和当前总时间的最大值(保证顺序性),再加 111 秒按键时间,用公式表达即为: > ntime←max⁡{timeo+∣ai−poso/posb∣,s}ntime \\leftarrow \\max\\{timeo+|a\_i-poso/posb|,s\\}ntime←max{timeo+∣ai​−poso/posb∣,s} - 更新机器人位置、对应完成时间和总时间。 ## 代码实现[#](#代码实现) ``` #include using namespace std; // 存储每个命令的结构体:机器人类型和目标位置 struct Command{ char robot; int pos; }a[100]; int t,n,poso,posb,timeo,timeb,s,p,ntime; char c; // 初始化函数:重置机器人初始状态 void init(){ poso=1; // 初始位置均为1 posb=1; timeo=0; // 初始时间为0 timeb=0; s=0; // 总时间初始为0 } int main(){ cin>>t; for (int k=1;k<=t;k++) { cin>>n; for (int i= 0;i>a[i].robot>>a[i].pos; } init(); // 初始化状态 for(int i=0;i 本文讲述了如何使用 C++ 完成洛谷的 题解:P14702 \[ICPC 2024 Tehran R\] Boat,思路清晰、排版精美 次阅读 [| 次评论](#waline) [题目传送门 ↗](https://www.luogu.com.cn/problem/P14702) 贪心,细节较多。 ## 思路分析[#](#思路分析) 先特判无解情况。 提示 - 如果某个重量大于最大载重量 www,输出 `−1`,结束。 - 如果最轻的两个人重量之和超过了 www,即**无人**可以当船夫,输出 `−1`,结束。 否则**一定**有解,尽量让**两人配对上船**,为了用最少次数,先 sort 从小到大排序,再让最轻的人作为船夫,分为两种情况: - 如果 ai+a1≤wa\_i+a\_1 \\leq wai​+a1​≤w,可以和最轻的人一起上船,可载两人。这样运送要 222 次,ans←ans+2ans \\leftarrow ans+2ans←ans+2。 - 否则,不可以和最轻的人一起上船,只载一人。这样运送要 444 次,ans←ans+4ans \\leftarrow ans+4ans←ans+4。 最后船夫不回来,所以输出 ans−1ans-1ans−1。 ## 代码[#](#代码) 按思路写即可,注意细节,这里不放了。 ## 结语[#](#结语) 感谢您的阅读! --- ## 题解:P14730 [ICPC 2022 Seoul R] Palindrome Type URL: https://blog.rusin7.com/article/p14730-sol 本文讲述了如何使用 C++ 完成洛谷的 P14730 [ICPC 2022 Seoul R] Palindrome Type,思路清晰、排版精美 ![题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/30 2 分钟 [题解](/tags/题解) / [c++](/tags/c++) # 题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type > 本文讲述了如何使用 C++ 完成洛谷的 P14730 \[ICPC 2022 Seoul R\] Palindrome Type,思路清晰、排版精美 次阅读 [| 次评论](#waline) [**纯享阅读区** ↗](https://www.luogu.com.cn/article/twhfrn73 "纯享阅读区") [题目传送门 ↗](https://www.luogu.com.cn/problem/P14730 "P14730 [ICPC 2022 Seoul R] Palindrome Type") ## 总体分析[#](#总体分析) **核心**:修改字符串 sss 使其成为回文串,记最小次数为 kkk,如果 k≤3k\\leq3k≤3,输出 kkk,否则输出 `-1` 。 因此,可以从 k\=0∼3k=0\\sim3k\=0∼3 依次进行 DFS 搜索,只要有一次成功,输出 kkk,结束。 ## 思路引导[#](#思路引导) {% note warning flat %} **提问** 如何 DFS **搜索**修改过程算出 kkk? {% endnote %} {% note success flat %} **DFS 函数** 使用 [双指针 ↗](https://oi-wiki.org/misc/two-pointer/)。 当 l 本文讲述了如何使用 C++ 完成洛谷的 P14731 \[ICPC 2022 Seoul R\] Parentheses Tree,思路清晰、排版精美 次阅读 [| 次评论](#waline) * * * [题目传送门 ↗](https://www.luogu.com.cn/problem/P14731 "P14731 [ICPC 2022 Seoul R] Parentheses Tree") ## 前置知识[#](#前置知识) STL 中的 stack 容器提供了一众成员函数以供调用,其中较为常用的有: - 定义 - 头文件 \\color{green}\\textbf{}。 - 元素访问 - `st.top()` 返回栈顶。 - 修改 - `st.push()` 插入传入的参数到栈顶。 - `st.pop()` 弹出栈顶。 - 容量 - `st.empty()` 返回是否为空。 - `st.size()` 返回元素数量。 部分内容来自 [栈 - OI Wiki ↗](https://oi-wiki.org/ds/stack/ "栈 - OI Wiki")。 ## 总体分析[#](#总体分析) **核心**:用栈匹配括号并在叶节点累加距离。 ## 思路引导[#](#思路引导) 提问 如何对左括号进行判断是否为叶节点? 成功 当 sis\_isi​ 为 `(` 时,如果栈非空,将栈顶替换为 false,再将 true 入栈。 提问 如何将答案进行累加? 成功 当 sis\_isi​ 为 `)` 时,如果栈顶 `(` 是叶子节点,先累加栈内元素数量,再弹出栈顶。 警告 不开 long long 见祖宗。 ## 核心代码[#](#核心代码) ``` cin>>s; for(char c:s){ if(c=='('){ if(st.size()){ st.pop(); st.push(false); }//替换操作 st.push(true); }else{ if(st.top()){ ans+=st.size()-1; }//累加栈内元素数量 st.pop();//弹出栈顶 } } cout< 本文讲述了如何使用 C++ 完成洛谷的 P8506 标题计数,思路清晰、排版精美 次阅读 [| 次评论](#waline) ## 前言[#](#前言) 本篇题解适合**刚学[字符串 ↗](https://www.luogu.com.cn/problem/list?type=luogu&page=1&tag=357)和[模拟 ↗](https://www.luogu.com.cn/problem/list?type=luogu&difficulty=1&page=1&tag=1)的同学**阅读,语言浅显易懂。谁让作者是个蒟蒻呢。 ## 题目分析[#](#题目分析) **核心条件**: - 第一个非空格字符**必须**是井号 `#`。 - 井号后面**必须**紧跟着**至少一个**空格且**不能**有多个井号相连(如 `##`)。 - 在井号后面的空格后**必须**有长度不为 000 的句子。 ## 思路引导[#](#思路引导) 提问 如何输入一行**含空格**的字符串? 成功 使用 string 类型自带的 `getline()` 。 提问 如何判断字符串是否为一级标题? 成功 联系我们刚分析完的核心条件,可以进行**模拟**。具体如下: - 首先,假设读入的字符串 sss 不是一级标题,flagflagflag 为 false 。再将 sss 从头到尾扫一遍。 - 如果 sis\_isi​ 是空格,直接跳过。 - 否则如果 flagflagflag 为 true ,说明已经满足核心条件中的 1、2 点,且现在 sis\_isi​ 不为空格,也满足第 3 点,计数器 +1+1+1。 - 否则如果 sis\_isi​ 是非 `#` 字符,sss 必定不是一级标题,跳出循环。 - 否则如果 sis\_isi​ 是 `#` 字符且满足核心条件中的 1、2 点,flagflagflag 为 true 。 - 否则 sss 必定不是一级标题,跳出循环。 ## 完整代码[#](#完整代码) ``` #include using namespace std; int n,pos,cnt; // cnt用于计数符合条件的标题 bool flag; // 标记是否满足标题的前置条件 string s; int main() { cin>>n; cin.ignore(); // 忽略n后面的换行符 while(n--) { getline(cin,s); // 读取一整行文本 flag=false; // 初始化标记 for(int i=0; i 本文讲述了如何使用 C++ 完成洛谷的 P8534 「Wdoi-2」比赤色更红的梦,思路清晰、排版精美 次阅读 [| 次评论](#waline) [题目传送门 ↗](https://www.luogu.com.cn/problem/P8534) ## 题意分析[#](#题意分析) **核心**:对于每组数据,判断 xxx 是否 ≥3\\ge 3≥3 或 ≥5\\ge 5≥5 并对应地将残机 +1+1+1,判断 sss 是否 ≥10000000\\ge 10000000≥10000000、≥20000000\\ge 20000000≥20000000、≥40000000\\ge 40000000≥40000000 或 ≥60000000\\ge 60000000≥60000000 并对应地将残机 +1+1+1。 ## 思路引导[#](#思路引导) 提问 如何处理多组数据? 成功 使用 `while` 循环语句,每次将 t−1t-1t−1,因为 t\=0t=0t\=0 时布尔值为 000, 即 false,所以将会跳出循环,此时循环语句正好执行 ttt 次。格式如下: ``` while(t--/*布尔表达式*/){ //执行____ } ``` cpp 提问 如何对 xxx 和 sss 的值进行判断? 成功 使用 `if` 分支语句,格式如下: ``` //普通版: if(/*布尔表达式*/){ //执行____ } //压行版: if(/*布尔表达式*/)//执行____(限一句) ``` cpp 警示 - 如果你将 sss 开 int ,那么你将喜提 WA\\color{E74C3C}{\\text{WA}}WA,25pts\\color{E74C3C}{\\text{25pts}}25pts。请注意观察数据范围! 别问我是[怎么知道的 ↗](https://www.luogu.com.cn/record/236917936) - 别忘了每次将 ansansans 初始化为 222。 ## 核心代码[#](#核心代码) 只提供 `while` 循环语句内的代码。 ``` ans=2; cin>>x>>s; if(x>=3)ans++; if(x>=5)ans++; if(s>=10000000)ans++; if(s>=20000000)ans++; if(s>=40000000)ans++; if(s>=60000000)ans++; cout< 我将背后的时间裁剪、折叠、蜷曲,揉捻成天上朵朵白云。 次阅读 [| 次评论](#waline) 1111 居中内容。 ## 追忆[#](#追忆) 我常常追忆过去。 生命瞬间定格在脑海。我将背后的时间裁剪、折叠、蜷曲,揉捻成天上朵朵白云。 云朵之间亦有分别:积云厚重,而卷云飘渺。生命里震撼的场景掠过我的思绪便一生无法忘怀,而更为普通平常的记忆在时间的冲刷下只留下些许残骸。追忆宛如入梦,太过清楚则无法愉悦自己的幻想,过分模糊却又坠入虚无。只有薄雾间的山水,面纱下的女子,那恰到好处的朦胧,才能满足我对美的苛求。 追忆总在不经意间将我裹进泛黄的纸页里。分别又重聚的朋友,推倒又重建的街道,种种线索协助着我从一个具体的时刻出发沿时间的河逆流而上。曾经的日子无法重来,我只不过是一个过客。但我仍然渴望在每一次追忆之旅中留下闲暇时间,在一个场景前驻足,在岁月的朦胧里瞭望过去的自己,感受尽可能多的甜蜜。美好的时光曾流过我的身体,我便心满意足。 过去已经凝固,我带着回忆向前,只是时常疏于保管,回忆也在改变着各自的形态。这给我的追忆旅程带来些许挑战。 我该在哪里停留?我问我自己。 --- ## 在 VS code 上远程管理 Github 仓库并自动化部署项目 URL: https://blog.rusin7.com/article/remote-github-repo-on-vs-code 如果GitHub远程是没有提交的空仓库然后再绑定哦。 2026/04/19 7 分钟 [vs code]() / [git](/tags/git) / [nodejs](/tags/nodejs) # 在 VS code 上远程管理 Github 仓库并自动化部署项目 > 如果GitHub远程是没有提交的空仓库然后再绑定哦。 次阅读 [| 次评论](#waline) ## 如果 GitHub 远程是没有提交的空仓库[#](#如果-github-远程是没有提交的空仓库) ``` git init git add -A git commit -m "🔄️ init:初始化 main 源码分支" git checkout -b main ``` bash 然后再绑定哦。 ## 绑定本地仓库到你已有的 GitHub 远程仓库[#](#绑定本地仓库到你已有的-github-远程仓库) 先把本地和远程仓库建立连接,Ctrl+Shift+\`调出 VS code 终端直接执行: ``` git remote add origin https://github.com/你的用户名/仓库名.git ``` bash **验证绑定成功**: ``` git remote -v ``` bash 终端输出下面这样,就代表绑定成功: ``` origin git@github.com:xxx/xxx.git (fetch) origin git@github.com:xxx/xxx.git (push) ``` bash {% note info flat %} 报错 `fatal: remote origin already exists`:说明之前绑过别的,先执行 `git remote remove origin` 解除绑定,再重新执行上面绑定命令即可。 {% endnote %} ## 拉取远程旧 main 分支内容,做安全备份(如果你的仓库原来有 main 分支,可选)[#](#拉取远程旧-main-分支内容做安全备份如果你的仓库原来有-main-分支可选) 远程 {% label main red %} 全是旧的 {% label dist red %} 文件,我们先把它拉到本地,备份成一个旧分支,绝对不覆盖本地源码,全程安全兜底。 ``` git fetch origin git branch old-main origin/main ``` bash 执行完,你本地就多了一个 {% emp old-main %} 备份分支,以前手动上传的所有文件全部永久保留,后续操作完全不会动它。 ## 重置本地 main 分支为纯净源码分支[#](#重置本地-main-分支为纯净源码分支) 你的 `.gitignore` 已经写好了 `dist`,会自动忽略打包文件夹,不会把 `dist` 提交到 {% label main red %} 分支。 ``` git checkout main git add . git commit -m "🔄️ init:初始化 main 源码分支" ``` bash ## 推送全新源码 main 分支[#](#推送全新源码-main-分支) 如果 {% label main red %} 分支已经有冲突文件: ``` git push -f origin main ``` bash 否则: ``` git push origin main ``` bash {% tip success %}GitHub 远程 {% label main red %} 分支:已经全部是你的项目源码,`dist` 文件夹被 .gitignore 自动忽略,完全不会上传到 {% label main red %}!{% endtip %} * * * ## 新建 gh-pages 分支,只存放静态文件[#](#新建-gh-pages-分支只存放静态文件) 这一步专门创建部署分支,全程独立,和 {% label main red %} 分支完全隔离,只存放打包后的 `dist` 静态文件。 ``` pnpm build cd dist && git init && git add . && git commit -m "init gh-pages" && git push -f git@github.com:你的用户名/仓库名.git HEAD:gh-pages && cd .. ``` bash {% tip success %}GitHub 远程 {% label gh-pages red %} 分支:里面只有 `dist` 静态网页文件,无任何源码,专门用于 GitHub Pages 网站部署。{% endtip %} * * * ## 日常开发[#](#日常开发) 你以后每次修改完代码,更新网页,只需要严格按这个顺序走,再也不用手动上传文件: ### Vite 项目[#](#vite-项目) #### 1\. 开发修改源码(全程在 main 分支)[#](#1-开发修改源码全程在-main-分支) 你改完源码后,更新到 GitHub 源码仓库: ``` git add . git commit -m "✨ UppubDatetime: 更新源码" git push origin main ``` bash #### 2\. 打包生成最新的 dist 文件[#](#2-打包生成最新的-dist-文件) 在 main 分支终端执行打包命令(根据你的项目,你的是 vite 项目) ``` npm run build # 或 pnpm build ``` bash 执行完,本地 `dist` 文件夹就会更新为最新打包文件。 {% note primary flat %} 回到主项目根目录,执行这 2 条全局 git 配置,永久关闭这个烦人的换行符警告: ``` git config core.autocrlf true git config core.safecrlf false ``` bash {% endnote %} #### 3\. 一键更新 gh-pages 部署网页[#](#3-一键更新-gh-pages-部署网页) ``` npm run build # 或 pnpm build cd dist && git init && git add . && git commit -m "uppubDatetime site" && git push -f git@github.com:你的用户名/你的仓库名.git HEAD:gh-pages && cd .. ``` bash - 打包最新静态文件 - 一键纯净推送 gh-pages,无任何多余文件 ### NextJs 项目[#](#nextjs-项目) #### 每次写完代码 →\\to→ 推源码(main)[#](#每次写完代码-to-推源码main) Ctrl+Shift+\` 打开终端,直接运行: ``` git add . git commit -m "更新项目源码" git push origin main ``` bash {% folding green, ✅ 作用 %} 把你的代码推送到小号 {% hideInline 看什么看,查\*\*\*\*\*\*,#FF7242,#fff %} 的 {% label main red %} 分支(你已经配置好锁死小号,直接推就行) {% endfolding %} ### 要发布网页 →\\to→ 推静态文件(gh-pages)[#](#要发布网页-to-推静态文件gh-pages) 还是在根目录,直接复制这一条完整命令运行: ``` npm run build && cd out && git add . && git commit -m "更新网页" && git push -f https://ru-sin@github.com/ru-sin/用户名.git HEAD:gh-pages && cd .. ``` bash {% note success flat %} 这条命令会自动 - 打包生成最新 `out` - 提交网页文件 - 强制推送到小号 {% label gh-pages red %} 分支 - 退回根目录 {% endnote %} * * * ## 高级做法(2 选 1)[#](#高级做法2-选-1) ### 推送 main 源码后自动推送 gh-pages 分支[#](#推送-main-源码后自动推送-gh-pages-分支) 访问 /settings/actions,下滑找到 `Workflow permissions`,勾选 Read and write permissions,点击 `Save` 就好了。 {% label main red %} 分支新建 `.github/workflows/deploy.yml`,直接复制代码如下: ``` name: 自动部署到 gh-pages on: push: branches: - main # 推送到 main 分支就自动触发 jobs: deploy: runs-on: ubuntu-latest steps: - name: 拉取代码 uses: actions/checkout@v4 with: persist-credentials: false - name: 安装依赖 run: npm install - name: 编译生成 out 文件夹 run: npm run build - name: 部署到 gh-pages uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./out ``` yml 这样就不需要推静态文件({% label gh-pages red %})分支了,直接推 {% label main red %} 即可。 ### build 后一行命令部署 dist[#](#build-后一行命令部署-dist) 安装工具。 ``` npm install gh-pages --save-dev ``` bash 在 `package.json` 里添加部署脚本。 ``` { "scripts": { "deploy": "gh-pages -d dist" } } ``` json 部署命令,可以自动部署到 gh-pages 分支。 ``` npm run build npm run deploy ``` bash {% tip success %}成功!{% endtip %} --- ## Rusin note 项目推荐 URL: https://blog.rusin7.com/article/rusin-note 推荐一个轻量的服务器部署 python 项目,欢迎大家交 PR,一起开发! ![Rusin note 项目推荐](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) 2026/08/13 / Update 2026/08/13 21 分钟 zh [建站](/tags/建站) / [github](/tags/github) / [开源项目](/tags/开源项目) / [教程](/tags/教程) # Rusin note 项目推荐 > 推荐一个轻量的服务器部署 python 项目,欢迎大家交 PR,一起开发! 次阅读 [| 次评论](#waline) [ rusin-dev / rusin-note Waiting for api.github.com... ??? ??? ??? ????? ](https://github.com/rusin-dev/rusin-note) 欢迎 Star 和 Fork 本项目哦! 本文章可能更新不够及时,请前往 [README ↗](https://github.com/rusin-dev/rusin-note) 获取最新版本。 ![屏幕截图](/images/screen.png) ## 产品特性[#](#产品特性) - **开箱即用的云端剪贴板**:基于 Flask 的轻量实现,可部署在 VPS 或 Vercel / AWS Lambda 等无服务器平台,用浏览器即可快速保存和访问文本内容。 - **公开与私有笔记**:支持随机短路径公开笔记,也支持访客账号下的私有笔记列表,兼顾临时分享和个人留存。 - **安全分享链接**:可为用户笔记生成带随机 token 的分享链接,并支持分享内容写回,便于跨设备协作。 - **Markdown 与 LaTeX 渲染**:只读页面和犇犇动态支持 Markdown、KaTeX 公式与 Pygments 代码高亮(代码块自动带行号),适合保存代码片段、说明文档和数学内容。编辑页实时渲染可手动开关。 - **犇犇动态**:内置轻量动态流,登录用户可发布内容,未登录用户可浏览,支持实时预览、分页加载和发布冷却。 - **多语言界面**:内置简体中文与 English,可手动切换,也可按浏览器语言自动选择。 - **部署友好**:配置集中在 `config.json`,支持笔记过期清理、会话超时、密码策略、反向代理真实 IP、HTTPS Cookie 等常见部署选项。无服务器部署时数据可接入外部 KV 存储(Vercel KV / Upstash),冷启动不丢数据。 - **基础防护完善**:包含 CSRF 防护、请求限流、保存限流、注册限流、内容安全清洗和代理头信任开关,降低公开部署风险。 ## 快速开始[#](#快速开始) ### 要求[#](#要求) python 版本 ≥\\geq≥ 3.10。 ### 本地开发[#](#本地开发) 1. 克隆代码 ``` git clone https://github.com/rusin-dev/rusin-note.git cd rusin-note ``` bash 2. 安装依赖 ``` pip install -r requirements.txt ``` bash 3. 启动服务 ``` python3 -m app ``` bash 然后打开 [https://localhost:8080 ↗](https://localhost:8080) 查看效果。 ### 线上部署[#](#线上部署) #### 方式一:Vercel(无服务器,推荐)[#](#方式一vercel无服务器推荐) [![Deploy to Vercel](https://vercel.com/button) ↗](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Frusin-dev%2Frusin-note&&env=RUSIN_SECRET_KEY) 项目已内置 Vercel 配置(`vercel.json` + `api/index.py`),零配置即可部署: 1. 在 [Vercel ↗](https://vercel.com) 导入本仓库(Framework Preset 选择 **Other** 即可,Python 运行时自动识别)。 2. 存储后端二选一: - **Neon(PostgreSQL)(推荐)**:在 Vercel 的 Storage / Marketplace 绑定 [Neon ↗](https://vercel.com/marketplace/neon),Vercel 会自动注入 `DATABASE_URL` 环境变量(Vercel KV 已停服,这是目前 Vercel 官方推荐的持久化方案); - **Upstash Redis**:在 Vercel Marketplace 安装 Upstash Redis,手动把 `KV_REST_API_URL` 与 `KV_REST_API_TOKEN` 填入项目环境变量。 - 两者都设置时优先用 Upstash。 3. 在项目设置中新增环境变量 `RUSIN_SECRET_KEY`(任意随机长字符串,用于会话/CSRF 签名,**必填**;不设置则每次冷启动随机,登录态会失效)。 4. 部署完成后,数据(笔记、用户、会话、分享、犇犇)全部存于 Neon/Upstash,多实例共享、冷启动不丢。 可选:设置 `REDIS_URL`(Redis 连接串,如 Upstash 或自建 Redis)后,页面缓存切换为共享 Redis、限流计数也在多实例间共享;不设置时页面缓存用进程内 SimpleCache、限流按实例内存计数(Zeabur 上的用法见下方章节)。 > 提示:无服务器平台默认 `trust_proxy_headers: true`、`secure_cookies: true`(已写入 `config.json`)。本地开发如需关闭请自行修改。 #### 方式二:AWS Lambda(无服务器)[#](#方式二aws-lambda无服务器) 项目根目录提供 `lambda_handler.py`(基于 Mangum 适配 WSGI): 1. 打包仓库上传(包含 `templates/`、`config.json` 等); 2. 处理程序设为 `lambda_handler.handler`,配 API Gateway 代理集成; 3. 环境变量与 Vercel 相同(`KV_REST_API_URL` / `KV_REST_API_TOKEN` / `RUSIN_SECRET_KEY`); 4. 内存建议 ≥ 512MB(Markdown 渲染需要)。 #### 方式三:VPS / 传统服务器[#](#方式三vps--传统服务器) 连接你的服务器,然后 1. 克隆代码 ``` git clone https://github.com/rusin-dev/rusin-note.git cd rusin-note ``` bash 2. 安装依赖 ``` pip install -r requirements.txt ``` bash 3. 启动服务 ``` python3 -m app # 后台运行 nohup python3 -m app > app.log 2>&1 & ``` bash 4. 配置 Nginx(可选) 创建站点配置 ``` sudo nano /etc/nginx/sites-available/rusin-note ``` bash 复制以下内容: ``` server { listen 80; server_name _ your_domain.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` nginx > 使用 Nginx/Cloudflare 反代后,请将 `config.json` 中的 `trust_proxy_headers` 设为 `true`, 服务端才会信任代理头按真实客户端 IP 限流(默认关闭以杜绝伪造头绕过限流)。 代理头可信度从高到低:`CF-Connecting-IP`(Cloudflare 直连)→ `X-Real-IP`(Nginx)→ `X-Forwarded-For` 最右一项(Nginx 追加的真客户端),客户端伪造的 XFF 左侧项不会被采信。 > 注意:仓库内 `config.json` 默认已为无服务器平台开启 `trust_proxy_headers` 与 `secure_cookies`,VPS 部署请按需改回 `false`(HTTP 环境下 Secure Cookie 会被浏览器拒绝)。 ``` # 启用并重载 sudo ln -s /etc/nginx/sites-available/rusin-note /etc/nginx/sites-enabled sudo nginx -t && sudo systemctl reload nginx sudo ufw allow 'Nginx Full' ``` bash #### Zeabur VPS 自动部署[#](#zeabur-vps-自动部署) 使用 Zeabur 从 GitHub 自动部署时,应用目录会在每次部署时重新构建。为了避免剪贴板、用户、分享链接和犇犇动态被清空,请把运行数据写入持久化卷: 1. 在 Zeabur 项目中打开当前服务。 2. 进入 `Storage` / `Volumes`,新增一个 Volume。 3. 将 Volume 挂载路径设置为 `/data`。 4. 进入 `Environment Variables`,新增环境变量 `RUSIN_DATA_DIR=/data`。 5. 重新部署服务。 不要将 Volume 挂载到项目根目录,否则可能覆盖部署出来的应用代码。设置完成后,运行数据会保存在 `/data` 下: ``` /data/notes/ /data/users.json /data/sessions.json /data/shares.json /data/benben.json /data/log/ ``` plaintext #### Zeabur 启用 Redis(页面缓存 + 共享限流)[#](#zeabur-启用-redis页面缓存--共享限流) Zeabur 是 PaaS 平台,不需要也不建议在容器里 `apt install redis`(构建产物每次重新部署会重建,装了也存不住);标准做法是添加一个托管 Redis 服务,Zeabur 会自动把连接信息注入到其他服务: 1. 在 Zeabur 项目中打开 **Market** / **Marketplace**,搜索并添加 **Redis** 服务(内置 `redis/redis-stack-server` 镜像,Zeabur 会为它生成随机密码)。 2. 添加完成后,Zeabur 会自动向项目内其他服务注入 `REDIS_CONNECTION_STRING`、`REDIS_HOST`、`REDIS_PORT`、`REDIS_PASSWORD` 等变量(也可在 Redis 服务的「操作指南/Instructions」里查看连接信息)。 3. 回到本服务,进入 **Variables / 环境变量**,新增变量(跨服务引用,自动拼出带密码的连接串): ``` REDIS_URL = ${REDIS_CONNECTION_STRING} ``` plaintext 等价于 `redis://:密码@服务名:6379`。 4. 重新部署服务。启动时应用会主动 `PING` Redis:连通则页面缓存(首页/笔记/犇犇等)切换为 Redis 共享后端、限流计数也存入 Redis(多实例共享);未连通则日志输出 `Redis 缓存不可达,已降级到 SimpleCache` 并退回进程内缓存,不影响功能。 > 说明:Redis 只负责缓存与限流;剪贴板、用户、分享、犇犇等业务数据仍由上面挂载的 `/data` 卷(`file` 后端)保存,两者互不影响。若追求数据多实例共享 / 不丢,可改用 `postgres` 或 `upstash` 后端(见下节)。 ### 存储后端说明(无服务器关键)[#](#存储后端说明无服务器关键) 存储层(`app/storage.py`)提供四种后端,由 `RUSIN_STORAGE` 环境变量显式指定,未指定时自动识别: | 后端 | 启用方式 | 说明 | | --- | --- | --- | | file | 默认(本地/VPS) | 数据写入 RUSIN_DATA_DIR(默认当前目录),布局与上表一致 | | upstash | 设置 KV_REST_API_URL + KV_REST_API_TOKEN(Upstash Redis 的 REST 接口) | 数据存于外部 KV,多实例共享、冷启动不丢;纯 HTTPS 请求,任意支持 Python 的无服务器平台可用 | | postgres | 设置 DATABASE_URL(Neon / 任意 PostgreSQL,Vercel 绑定 Neon 后自动注入) | 数据存于 PostgreSQL 表(storage_kv / storage_notes),多实例共享、冷启动不丢;跨实例互斥用 PG advisory lock | | memory | RUSIN_STORAGE=memory(无服务器平台未配置上述存储时自动启用) | 纯内存,重启/冷启动清空,适合体验或临时部署 | 自动识别优先级:显式 `RUSIN_STORAGE` > `KV_REST_API_URL`+`KV_REST_API_TOKEN`(upstash)> `DATABASE_URL`(postgres)> 无服务器平台(memory)> 本地(file)。 - 犇犇动态已从纯内存改为持久化(外部存储可用时重启不丢,最多保留 `benben.max_posts` 条,默认 200)。 - 无服务器环境(检测到 `VERCEL` / `NETLIFY` / `AWS_LAMBDA_FUNCTION_NAME` 环境变量)不启动后台守护线程,清理任务改为请求内机会式执行;日志回退到 stderr(进入平台日志流)。 - `RUSIN_SECRET_KEY` 在无服务器平台必须设置;未设置时若后端可持久化(file/upstash/postgres)会自动生成并存储,否则退回随机密钥(重启后登录态失效)。 - 环境变量清单见 `.env.example`。 ## 项目结构[#](#项目结构) ``` rusin-note:. │ config.json(配置项) │ contributing.md(协作指南) │ Disclaimer-en.md(英文免责声明) │ Disclaimer.md(免责声明) │ favicon.ico │ README.md │ README_en.md │ requirements.txt(Python 依赖) │ zbpack.json(打包配置) │ vercel.json(Vercel 无服务器部署配置) │ lambda_handler.py(AWS Lambda 入口) │ .env.example(环境变量示例) │ ├─api(无服务器入口) │ index.py(Vercel Python 入口) │ ├─app(核心代码) │ │ __init__.py │ │ __main__.py(入口:python3 -m app) │ │ auth.py(密码哈希与会话认证) │ │ background.py(后台清理任务) │ │ config.py(配置加载与全局常量) │ │ extensions.py(Flask 扩展实例) │ │ i18n.py(多语言支持) │ │ logger.py(日志记录) │ │ middleware.py(请求钩子与限流辅助) │ │ notes.py(笔记操作与统计) │ │ storage.py(存储层:file / memory / upstash / postgres 后端) │ │ store.py(用户/会话/分享/犇犇数据存储) │ │ theme.py(主题与静态资源辅助) │ │ utils.py(通用工具函数) │ │ wsgi.py(WSGI 入口) │ │ │ └─views(蓝图与路由) │ __init__.py(蓝图注册) │ _helpers.py(视图辅助函数) │ auth.py(登录与注册) │ benben.py(犇犇动态) │ home.py(首页) │ share.py(分享页面) │ static_routes.py(静态与说明页面) │ user.py(用户与用户笔记) │ world.py(公开笔记) │ world_short.py(短链接公开笔记) │ ├─templates(Jinja2 模板) │ │ base.html(基础布局) │ │ count.html(统计页面) │ │ disclaimer.html(免责声明页面) │ │ home.html(首页) │ │ │ ├─auth(认证页面) │ ├─benben(犇犇页面) │ ├─errors(错误页) │ ├─notes(笔记页面) │ ├─partials(公共片段) │ └─share(分享页面) │ ├─image(图片资源) │ logo.png │ ├─.github │ │ issue-labeler.yml(Issue 标签配置) │ │ │ ├─ISSUE_TEMPLATE(Issue 模板) │ └─workflows(GitHub Actions) │ auto-merge.yml(自动合并) │ check.yml(检查) │ codeql.yml(CodeQL 分析) │ labeler.yml(自动打标签) │ release.yml(发布) │ trigger-fork-sync.yml(触发 Fork 同步) │ upstream-sync.yml(上游同步) ``` plaintext ### 配置项解析[#](#配置项解析) - `max_note_size_kb`:笔记最大大小(单位:**KB**)默认 512512512(即 0.50.50.5 MB)。 - `sitename`:网页名称。填你的站点名。 - `rate_limit` 速率限制。 - `window_seconds` : 时间 ttt,默认 606060; - `max_requests` :请求数 sss,默认 303030; ttt 秒内最大请求 sss 次。 - `get_rate_limit` GET 请求独立限流。 - `window_seconds` :时间 ttt,默认 606060; - `max_requests` :请求数 sss,默认 454545; ttt 秒内 GET 请求最大 sss 次(含页面加载、favicon 等)。 - `save_rate_limit` 保存类 POST 独立限流(笔记保存/分享写回)。 - `window_seconds` :时间 ttt,默认 606060; - `max_requests` :请求数 sss,默认 120120120; ttt 秒内保存笔记最多 sss 次,与全局 POST 限流(`rate_limit`)互不干扰,避免频繁保存被误伤。 - `register_rate_limit` 注册速率限制(单IP注册账号限制)。 - `window_seconds` :时间 ttt,默认 120120120; - `max_requests` :请求数 sss,默认 111; ttt 秒内单个IP最多注册 sss 个账号,防止恶意批量注册。 - `trust_proxy_headers`:是否信任反向代理传递的 `X-Forwarded-For` / `X-Real-IP` 头,默认 `false`。 **安全说明**:默认关闭,限流一律基于 TCP 直连 IP,防止客户端伪造请求头绕过限流。仅当部署在可信反向代理(如 Nginx)之后才置为 `true`。 - `secure_cookies`:会话 Cookie 是否附加 `Secure` 标志,默认 `false`。 **安全说明**:仅当通过 HTTPS 访问时置为 `true`,否则浏览器会拒绝在 HTTP 下回传 Cookie。 - `id_generation` 随机 url 配置。 - `length` :长度,默认 444; - `use_uppercase` :是否使用大写字母,默认 `false`; - `use_lowercase` :是否使用小写字母,默认 `true`; - `use_digits` :是否使用数字,默认 `false`; - `share_token` 分享链接 token 配置。 - `length` :长度,默认 646464; - `use_uppercase` :是否使用大写字母,默认 `true`; - `use_lowercase` :是否使用小写字母,默认 `true`; - `use_digits` :是否使用数字,默认 `true`; - `session_timeout` 单次会话时间。 - `enabled` :是否开启,默认 `false`; - `minutes` :设定时长,(单位:**分钟**)默认 151515; 当时间超过设定时,将登出访客账号。 - `note_expiration` 笔记自动清除(剪贴板超过保存时间自动删除)。 - `enabled` :是否开启,默认 `false`; - `hours` :保存时长(单位:**小时**)默认 242424; 开启后,超过设定小时数未被修改的剪贴板(公开+私有)将被后台线程自动删除,每 30 分钟扫描一次。 - `global_cdn` 全局前端静态资源 CDN 基础地址。 - 默认 `https://cdn.jsdmirror.cn`; 前端资源统一从该地址拼接加载:FontAwesome 图标、marked 编辑器脚本、DOMPurify 清洗库与 KaTeX 公式(路径均为 `npm/` 形式,因此也兼容 `https://cdn.jsdelivr.net` 等 npm CDN)。可按网络环境在 config.json 中整体替换,无需改代码。 - `latex_render` LaTeX 公式渲染。 - `enabled` :是否开启,默认 `true`; - KaTeX 静态资源从 `global_cdn` 基础地址拼接(默认 jsdmirror,可换 jsdelivr 等); 开启后,Markdown 只读页面支持 `$...$` 行内公式与 `$$...$$` 块级公式(KaTeX 洛谷同款,客户端渲染,无需服务端依赖)。 - `code_highlight` 代码高亮(highlight.js,客户端渲染)。 - `enabled` :是否开启,默认 `true`; 开启后,所有 Markdown 渲染处(笔记只读页、编辑页实时预览、犇犇动态、免责声明)的代码块自动语法高亮并显示行号,跟随站点浅色/暗色主题切换,无需服务端依赖。 - `avatar` 用户头像(通过第三方服务生成,显示在导航栏当前用户、犇犇动态发布者与用户笔记列表标题处)。 - `enabled` :是否开启,默认 `true`;置 `false` 后完全关闭头像显示; - `url_template` :头像 URL 模板,默认 `https://cn.cravatar.com/avatar/{hash}?d=identicon&f=y`。支持两个占位符:`{hash}`(`md5(用户名)` 小写十六进制)、`{username}`(URL 编码后的用户名)。由于本站用户没有邮箱,默认用 `md5(用户名)` 作为哈希,`d=identicon` 会让 Gravatar 系服务为每个哈希生成确定性的几何头像;也可换成其他按用户名生成头像的服务(如 DiceBear:`https://api.dicebear.com/9.x/identicon/svg?seed={username}`); - `size` :模板中的默认尺寸(当前仅作为备用值,模板内按位置使用固定尺寸)。 - `password_policy`:密码策略,定义访客密码的复杂度要求。 - `min_length`:密码最小长度,默认 `8`; - `max_length`:密码最大长度,默认 `128`(硬上限 `128`,防止超长密码进入 PBKDF2 慢哈希消耗 CPU); - `require_uppercase`:是否必须包含大写字母,默认 `true`; - `require_lowercase`:是否必须包含小写字母,默认 `true`; - `require_digits`:是否必须包含数字,默认 `true`; - `require_special`:是否必须包含特殊符号(不含 `/ \ ( ) " '`),默认 `true`; - `RUSIN_DATA_DIR`:可选环境变量,用于指定运行数据目录,默认当前项目目录(仅 `file` 后端使用)。 笔记、用户、会话、分享和日志会写入该目录下的 `notes/`、`users.json`、`sessions.json`、`shares.json`、`benben.json`、`log/`。在 Zeabur 等自动部署平台上建议挂载持久化卷到 `/data`,并设置 `RUSIN_DATA_DIR=/data`,避免每次部署清空剪贴板数据。 - `RUSIN_STORAGE`:可选环境变量,显式指定存储后端:`file`(本地/VPS,默认)、`memory`(纯内存)、`upstash`(外部 KV)、`postgres`(Neon/PostgreSQL)。未指定时自动识别:设置了 `KV_REST_API_URL` / `KV_REST_API_TOKEN` 用 `upstash`,设置了 `DATABASE_URL` 用 `postgres`,检测到无服务器平台环境变量用 `memory`,否则 `file`。详见上方「存储后端说明」。 - **多语言**:界面支持简体中文与 English。导航栏右侧提供语言切换链接(`/lang/zh` / `/lang/en`),选择后通过 Cookie(`rusin-lang`)记住偏好;未设置时自动按浏览器 `Accept-Language` 判断,默认中文。切换后全站文本(导航、按钮、提示、错误信息、犇犇预览等)即时切换语言。 - `benben` 犇犇动态(`/benben`,登录可发布、未登录只读)。 - `max_length`:单条犇犇最大长度(单位:**字符**),默认 `1024`(约 1KB); - `page_size`:每批加载条数,默认 `50`; - `cooldown_seconds`:单个用户两次发布犇犇的最小间隔(单位:**秒**),默认 `3`; - `max_height_px`:犇犇内容渲染后的最大显示高度(单位:**px**),默认 `1000`,超出部分在内容区内滚动; - `max_posts`:犇犇持久化条数上限,默认 `200`(外部存储单键体积控制,超出丢弃最旧); 内容支持 Markdown 与 LaTeX 公式(`$...$` / `$$...$$`,依赖 `latex_render` 开关),发布表单带实时预览(客户端 marked.js 渲染,预览同样过滤危险标签与链接);渲染时经 bleach 安全清洗防止 XSS;每页显示 `page_size` 条,通过「加载更多」分批加载,加载与发布均受请求速率限制(GET/POST 限流),发布还受单用户冷却限制(`cooldown_seconds`);每条犇犇头部展示发布者 IP(按 `trust_proxy_headers` 决定是否信任代理头,旧数据无 IP 字段时不显示)。 --- ## 单源最短路算法 URL: https://blog.rusin7.com/article/shortest-path 本文将会单源最短路的定义,并给出 SPFA、Bellman-Ford、Dijkstra 等多种用于求单源最短路的算法并进行比较。 2026/09/05 / Update 2026/09/29 11 分钟 zh [c++](/tags/c++) / [笔记](/tags/笔记) # 单源最短路算法 > 本文将会单源最短路的定义,并给出 SPFA、Bellman-Ford、Dijkstra 等多种用于求单源最短路的算法并进行比较。 次阅读 [| 次评论](#waline) ## 定义[#](#定义) **单源最短路**的定义:给定一个起点,求它到所有其他点的最短距离。 注 这里给出的定义较宽泛,没有提到边权的非负性。 在做题过程中,这点需要注意,并根据题面选择算法。 现在,来看看怎么解决此类问题。 模板题: [P3371 【模板】单源最短路径(弱化版) ↗](https://www.luogu.com.cn/problem/P3371) [P4779 【模板】单源最短路径(标准版) ↗](https://www.luogu.com.cn/problem/P4779) ## Dijkstra 算法[#](#dijkstra-算法) ### 算法思想[#](#算法思想) **前提**:所有边权非负。 Dijkstra 核心思想:贪心 + 逐步确定。 想象从起点 sss 出发,初始只知道到 sss 自己的距离是 000,到其他点都设为无穷大。然后不断做一件事: > 在**还没确定最短距离**的点中,选一个**当前距离最小**的点,这个距离就是它的最终最短距离。 反证法:如果这个距离不是它的最终最短距离,则必存在一条距离更短的路,但不可能通过其他未确定点再绕路到 uuu 得到更短距离,因为任何绕路都会先经过一个距离更大的点,再加上非负边权,只会更远。故假设不成立,结论成立。 所以我们可以把这个点“确定”下来,并用它去更新它的邻接点,直到所有点都被最终最短距离都被确定。 ### 算法步骤[#](#算法步骤) sss 表示源点。 初始化整个 disdisdis 为 INF,然后令 diss\=0dis\_s = 0diss​\=0。 遍历最多 nnn 次,每次确定一个点 uuu 的最终最短距离(松弛): - 在所有未确定的点中,找到 disudis\_udisu​ 最小的点 uuu。 - 将 uuu 标记为已确定,此时 disudis\_udisu​ **已经是** sss 到 uuu 的最短距离,后续不会再被更新。 - 如果没有任何未确定的点,则说明所有点最短距离已确定,可以 `break`。否则遍历 uuu 的所有出边 u→vu \\to vu→v,如果 disu+w using namespace std; const int N=10005,M=500005; int n,m,s,head[N],cnt,dis[N],vis[N]; struct edge{ int w,to,nxt; }e[M]; void add(int u,int v,int w){ e[++cnt].w=w; e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } void dij(int s){ for(int i=0;i>n>>m>>s; memset(head,-1,sizeof head); for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; add(u,v,w); } dij(s); for(int i=1;i<=n;++i){ if(dis[i]==0x3f3f3f3f)cout<<2147483647<<' '; else cout< #define pii pair using namespace std; const int N=100005,M=200005; int n,m,s,head[N],cnt,dis[N],vis[N]; struct edge{ int w,to,nxt; }e[M]; void add(int u,int v,int w){ e[++cnt].w=w; e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } priority_queue,greater >pq; void dij(int s){ for(int i=0;i>n>>m>>s; memset(head,-1,sizeof head); for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; add(u,v,w); } dij(s); for(int i=1;i<=n;++i){ if(dis[i]==0x3f3f3f3f)cout<<2147483647<<' '; else cout< using namespace std; const int N=2e3+5,M=3e3+5; int T,n,m,cnt,dis[N]; struct edge{ int u,v,w; }e[2*M]; void add(int u,int v,int w){ e[++cnt]={u,v,w}; } bool BellmanFord(){ bool f=0; for(int i=1;i<=n;++i){ bool upd=0; for(int j=1;j<=cnt;++j){ int u=e[j].u,v=e[j].v,w=e[j].w; if(dis[u]!=0x3f3f3f3f&&dis[u]+w>T; while(T--){ cin>>n>>m; cnt=0; for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; if(w>=0){ add(u,v,w); add(v,u,w); }else{ add(u,v,w); } } for(int i=0;i using namespace std; const int N=10005,M=500005; int n,m,s,head[N],cnt,dis[N],vis[N],inq[N]; struct edge{ int w,to,nxt; }e[M]; void add(int u,int v,int w){ e[++cnt].w=w; e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } queueq; void spfa(int s){ for(int i=0;i>n>>m>>s; memset(head,-1,sizeof head); for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; add(u,v,w); } spfa(s); for(int i=1;i<=n;++i){ if(dis[i]==0x3f3f3f3f)cout<<2147483647<<' '; else cout< using namespace std; const int N=2e3+5,M=3e3+5; int T,n,m,head[N],cnt,dis[N],inq[N],quecnt[N]; struct edge{ int w,to,nxt; }e[2*M]; void add(int u,int v,int w){ e[++cnt].w=w; e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } queueq; bool spfa(){ for(int i=0;i=n)return true; inq[v]=1; } } } } return false; } int main(){ cin>>T; while(T--){ cin>>n>>m; cnt=0; memset(head,-1,sizeof head); memset(inq,0,sizeof inq); memset(quecnt,0,sizeof quecnt); while(!q.empty())q.pop(); for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; if(w>=0){ add(u,v,w); add(v,u,w); }else{ add(u,v,w); } } cout<<(spfa()?"YES":"NO")<<'\n'; } return 0; } ``` cpp 更多算法待补充…… ## 对比[#](#对比) | 算法 | 能否处理负权边 | 是否判负环 | 时间复杂度 | 实现难度 | 稳定性 | | --- | --- | --- | --- | --- | --- | | Dijkstra(朴素) | 不能 | 不能 | O(n2+m)O(n² + m)O(n2+m) | 简单 | 稳定 | | Dijkstra(堆优化) | 不能 | 不能 | O((n+m)logm)O((n+m) log m)O((n+m)logm) | 中等 | 稳定 | | Bellman-Ford | 能 | 能 | O(nm)O(nm)O(nm) | 较简单 | 稳定 | | SPFA | 能 | 能 | 平均 O(km)O(km)O(km),最坏 O(nm)O(nm)O(nm) | 中等 | 不稳定(可被卡) | ## 结语[#](#结语) 在 [NOI 大纲 2025 修订版 ↗](https://www.noi.cn/upload/resources/file/2025/04/18/NOI_Syllabus_Edition_2025.pdf) 中,单源最短路位于提高组 2.2.42.2.42.2.4 中的 7.图论算法中的第【6】项,是图论中较为基础的算法。学会它,也可以为以后更多更复杂的图论算法打下坚实的基础。 --- ## 题解 URL: https://blog.rusin7.com/article/solution Posts in category: 题解 # 题解 [](/article/ccf "Previous: 信竞")[](/article/tech "Next: 技术") 第 1 页 - 展示 9 篇中的 9 篇文章 [按年份查看所有文章 →](/archives) - [![题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ! 本文讲述了如何使用 C++ 完成洛谷的 AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!,思路清晰、排版精美 4 分钟](/article/at-pakencamp-2020-day1-d-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P13361 \[GCJ 2011 Qualification\] Bot Trust](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 题解:P13361 \[GCJ 2011 Qualification\] Bot Trust 本文讲述了如何使用 C++ 完成洛谷的 P13361 \[GCJ 2011 Qualification\] Bot Trust」水落溪流浅浅,思路清晰、排版精美 4 分钟](/article/p13361-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P8506 标题计数](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 题解:P8506 标题计数 本文讲述了如何使用 C++ 完成洛谷的 P8506 标题计数,思路清晰、排版精美 3 分钟](/article/p8506-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P8534 「Wdoi-2」比赤色更红的梦](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 题解:P8534 「Wdoi-2」比赤色更红的梦 本文讲述了如何使用 C++ 完成洛谷的 P8534 「Wdoi-2」比赤色更红的梦,思路清晰、排版精美 2 分钟](/article/p8534-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P14702 \[ICPC 2024 Tehran R\] Boat](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/04/03 题解:P14702 \[ICPC 2024 Tehran R\] Boat 本文讲述了如何使用 C++ 完成洛谷的 题解:P14702 \[ICPC 2024 Tehran R\] Boat,思路清晰、排版精美 2 分钟](/article/p14702-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/04/03 题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree 本文讲述了如何使用 C++ 完成洛谷的 P14731 \[ICPC 2022 Seoul R\] Parentheses Tree,思路清晰、排版精美 2 分钟](/article/p14731-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:AT\_joi2024\_yo1c\_b 桁 (Digit)](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/30 题解:AT\_joi2024\_yo1c\_b 桁 (Digit) 本文讲述了如何使用 C++ 完成洛谷的 AT\_joi2024\_yo1c\_b 桁 (Digit),思路清晰、排版精美 1 分钟](/article/at-joi2024) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/30 题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type 本文讲述了如何使用 C++ 完成洛谷的 P14730 \[ICPC 2022 Seoul R\] Palindrome Type,思路清晰、排版精美 2 分钟](/article/p14730-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:CF2139B Cake Collection](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/23 题解:CF2139B Cake Collection 本文讲述了如何使用 C++ 完成洛谷的 CF2139B Cake Collection,思路清晰、排版精美 3 分钟](/article/cf2139b-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) --- ## 技术 URL: https://blog.rusin7.com/article/tech Posts in category: 技术 # 技术 [](/article/solution "Previous: 题解")[](/article/life "Next: 生活") 第 1 页 - 展示 13 篇中的 13 篇文章 [按年份查看所有文章 →](/archives) - [2026/08/31 Cyanwind 主题 markdown 语法 学习 Markdown 的基础语法,从入门到精通。 17 分钟 zh ](/article/how-to-use-markdown) - [ 教程 ](/tags/教程) - [ markdown ](/tags/markdown) - [![Rusin note 项目推荐](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) 2026/08/13 Rusin note 项目推荐 推荐一个轻量的服务器部署 python 项目,欢迎大家交 PR,一起开发! 21 分钟 zh](/article/rusin-note) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ 开源项目 ](/tags/开源项目) - [ 教程 ](/tags/教程) - [2026/01/11 MDX 组件使用:User & Advanced 文章内组件(Aside/Tabs 等)与高级组件(LinkPreview/GithubCard 等)的使用方式。 1 分钟 zh ](/article/mdx-components) - [ markdown ](/tags/markdown) - [2026/01/11 写作指南:Markdown / MDX 主题内支持的 Markdown 扩展、数学公式、代码高亮与一些写作约定。 1 分钟 zh ](/article/writing-markdown-mdx) - [ markdown ](/tags/markdown) - [![在 VPS 上部署洛谷保存站](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) 2026/08/11 在 VPS 上部署洛谷保存站 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) 8 分钟](/article/deploy-lg-saver) - [ 云服务器 ](/tags/云服务器) - [ 建站 ](/tags/建站) - [ 教程 ](/tags/教程) - [2026/06/07 在 Hexo 中复现洛谷插件 前言OIer都知道,洛谷中有个,非常好用,效果如下:succ 13 分钟 ](/article/luogu-plugin-in-hexo) - [ hexo ](/tags/hexo) - [ 安知鱼美化 ](/tags/安知鱼美化) - [2026/05/14 拯救谷歌和 Github!你的新“自行车” 快速安装,找到最新版本,安装包选择方式:Windows:De 1 分钟 ](/article/devsidecar) - [ git ](/tags/git) - [2026/05/12 Vercel 仅部署指定分支的方法 如何指定特殊分支? 从中选择的项目,在侧边栏中打开Settings 3 分钟 ](/article/vercel-deploying-only-1-branch) - [ git ](/tags/git) - [2026/04/20 对单一仓库配置小号以远程管理小号仓库 命令行操作给这个仓库单独设置小号仅本地生效把远程地址绑定到小 1 分钟 ](/article/configure-a-single-warehouse) - [ vs code ]() - [ git ](/tags/git) - [2026/04/19 在 VS code 上远程管理 Github 仓库并自动化部署项目 如果GitHub远程是没有提交的空仓库然后再绑定哦。 7 分钟 ](/article/remote-github-repo-on-vs-code) - [ vs code ]() - [ git ](/tags/git) - [ nodejs ](/tags/nodejs) - [![侧边栏添加个性定位欢迎信息](https://image.rusin7.com/file/hexo/cover/z7qOAkod.webp) 2026/04/06 侧边栏添加个性定位欢迎信息 前景介绍使用方法创建JS文件 9 分钟](/article/location-welcome-information) - [ hexo ](/tags/hexo) - [ 安知鱼美化 ](/tags/安知鱼美化) - [ 建站 ](/tags/建站) - [![在 arm64 中安装虚拟环境](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) 2026/04/03 在 arm64 中安装虚拟环境 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 3 分钟](/article/arm64-install-base) - [ git ](/tags/git) - [ nodejs ](/tags/nodejs) - [ 教程 ](/tags/教程) - [2026/03/23 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/article/free-domain) - [ 白嫖 ](/tags/白嫖) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ cloudflare ](/tags/cloudflare) - [ 教程 ](/tags/教程) --- ## 网络流笔记 URL: https://blog.rusin7.com/article/the-network-flow-notes 增广路ek模板Dinic模板,网络流的定义 2026/06/06 15 分钟 [笔记](/tags/笔记) / [c++](/tags/c++) # 网络流笔记 > 增广路ek模板Dinic模板,网络流的定义 次阅读 [| 次评论](#waline) ## 增广路[#](#增广路) ek 模板: ``` #include using ll=long long; using namespace std; const int N=205,M=5005; int n,m,s,t,cnt=1,head[N],pre[N],mf[N]; /* mf:当前增广路可通过水流 */ struct edge{ int nxt,to,w; }e[2*M]; void add(int u,int v,int w){ e[++cnt].w=w; e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } bool bfs(){ memset(mf,0,sizeof mf); queueq; q.push(s); mf[s]=1e9; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; if(mf[v]==0&&e[i].w){ mf[v]=min(mf[u],e[i].w); pre[v]=i; q.push(v); if(v==t)return 1; } } } return 0; } ll ek(){ ll fl=0; while(bfs()){ int v=t; while(v!=s){ int i=pre[v]; e[i].w-=mf[t]; e[i^1].w+=mf[t]; v=e[i^1].to; } fl+=mf[t]; } return fl; } int main(){ cin>>n>>m>>s>>t; for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; add(u,v,w); add(v,u,0); } cout< #define ll long long using namespace std; const int M=5005; int n,m,s,t,head[M],tot=1,d[M],cur[M]; struct edge{ int v,nxt; ll flow; }e[2*M]; void add(int u,int v,int w){ e[++tot]={v,head[u],w},head[u]=tot; } bool bfs(){ memset(d,0,sizeof d); memcpy(cur,head,sizeof head); queueq; q.push(s); d[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];~i;i=e[i].nxt){ int v=e[i].v; if(!d[v]&&e[i].flow){ d[v]=d[u]+1; if(v==t)return true; q.push(v); } } } return false; } ll dfs(int u,ll flow){ if(u==t||!flow)return flow; ll rest=flow; for(int &i=cur[u];~i;i=e[i].nxt){ int v=e[i].v; if(d[v]==d[u]+1&&e[i].flow){ ll k=dfs(v,min(rest,e[i].flow)); if(!k)d[v]=0; e[i].flow-=k,e[i^1].flow+=k; if(!(rest-=k))break; } } return flow-rest; } ll dinic(){ ll maxflow=0; while(bfs())maxflow+=dfs(s,INT_MAX); return maxflow; } int main(){ memset(head, -1, sizeof(head)); cin>>n>>m>>s>>t; for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; add(u,v,w),add(v,u,0); } cout<0c(u,v)-f(u,v) > 0c(u,v)−f(u,v)\>0,意味着残量网络中有一条从 uuu 到 vvv 的边。由于 u∈Su\\in Su∈S(从 sss 可达),那么 vvv 也可达,从而 v∈Sv\\in Sv∈S,与 v∈Tv\\in Tv∈T 矛盾。因此 f(u,v)\=c(u,v)f(u,v)=c(u,v)f(u,v)\=c(u,v)。 **接着证明** ∀ u∈T\\forall\\,u\\in T∀u∈T,v∈Sv\\in Sv∈S,原边 (u,v)(u,v)(u,v) 必然无流量。 还是反证法。若存在 u∈Tu\\in Tu∈T,v∈Sv\\in Sv∈S 使得 f(u,v)\>0f(u,v) > 0f(u,v)\>0,则反向残量 f(u,v)\>0f(u,v) > 0f(u,v)\>0,意味着残量网络中有一条从 vvv 到 uuu 的边。由于 v∈Sv\\in Sv∈S(从 sss 可达),那么 uuu 也可达,从而 u∈Su\\in Su∈S,与 u∈Tu\\in Tu∈T 矛盾。因此 f(u,v)\=0f(u,v)=0f(u,v)\=0。 **最后计算** ∣f∣\\left\\lvert f\\right\\rvert∣f∣。 由弱对偶性证明中的等式: ∣f∣\=∑u∈S, v∈Tf(u,v)−∑v∈T, u∈Sf(v,u)\\left\\lvert f\\right\\rvert = \\sum\_{u\\in S,\\,v\\in T} f(u,v) - \\sum\_{v\\in T,\\,u\\in S} f(v,u)∣f∣\=∑u∈S,v∈T​f(u,v)−∑v∈T,u∈S​f(v,u) 由“再证明”的结论,第一项中 f(u,v)\=c(u,v)f(u,v)=c(u,v)f(u,v)\=c(u,v);由“接着证明”的结论,第二项中 f(v,u)\=0f(v,u)=0f(v,u)\=0。因此: ∣f∣\=∑u∈S, v∈Tc(u,v)\=c(S,T)\\left\\lvert f\\right\\rvert = \\sum\_{u\\in S,\\,v\\in T} c(u,v) = c(S,T)∣f∣\=∑u∈S,v∈T​c(u,v)\=c(S,T) 这就找到了一个割,其容量等于 ∣f∣\\left\\lvert f\\right\\rvert∣f∣。证毕! 综上,证毕! ## Part. 4 增广路定理[#](#part-4-增广路定理) 定理:一个可行流 fff 是最大流当且仅当残量网络 GfG\_fGf​ 中不存在 sss 到 ttt 的路径(称为增广路)。 证明 (⇒\\Rightarrow⇒)若存在增广路 PPP,设 δ\=min⁡{r(u,v):(u,v)∈P}\>0\\delta = \\min\\{r(u,v): (u,v)\\in P\\} > 0δ\=min{r(u,v):(u,v)∈P}\>0。沿 PPP 增加 δ\\deltaδ 流量: - 对正向残量边:f(u,v)←f(u,v)+δf(u,v) \\leftarrow f(u,v) + \\deltaf(u,v)←f(u,v)+δ - 对反向残量边:f(v,u)←f(v,u)−δf(v,u) \\leftarrow f(v,u) - \\deltaf(v,u)←f(v,u)−δ 得到的新流仍满足容量约束,且 ∣f′∣\=∣f∣+δ\>∣f∣|f'| = \\left\\lvert f\\right\\rvert + \\delta > \\left\\lvert f\\right\\rvert∣f′∣\=∣f∣+δ\>∣f∣,故 fff 不是最大流。逆否命题成立。 (⇐\\Leftarrow⇐)若无增广路,定义 SSS 为 sss 在 GfG\_fGf​ 中可达的节点集,则 t∉St\\notin St∈/S。由 Part.3 “再证明”的证明过程,∣f∣\=c(S,T)\\left\\lvert f\\right\\rvert = c(S,T)∣f∣\=c(S,T),再由弱对偶性知 fff 是最大流。证毕! ## Part.5 Dinic 算法的分层图引理[#](#part5-dinic-算法的分层图引理) 定义:在残量网络中,定义 d(u)d(u)d(u) 为从 sss 到 uuu 的最短边数(BFS 距离)。边 (u,v)(u,v)(u,v) 称为允许边若 d(v)\=d(u)+1d(v) = d(u) + 1d(v)\=d(u)+1 且残量 \>0\>0\>0。所有允许边构成分层图 LfL\_fLf​。阻塞流是指在 LfL\_fLf​ 中无法再找到增广路的流。 引理:记 dk(t)d\_k(t)dk​(t) 为第 kkk 次阻塞流增广后 ttt 的距离。则 dk+1(t)\>dk(t)d\_{k+1}(t) > d\_k(t)dk+1​(t)\>dk​(t)。 证明 设 fff 是当前流,f′f'f′ 是增广一次阻塞流后得到的新流。考虑 Gf′G\_{f'}Gf′​ 中 sss 到 ttt 的最短路径 PPP。若 PPP 中存在一条边 (u,v)(u,v)(u,v) 在 GfG\_fGf​ 中不存在(即由增广操作新产生的反向边),则 f(v,u)\>0f(v,u) > 0f(v,u)\>0,这意味着在 GfG\_fGf​ 中 uuu 到 vvv 有容量 \>0\>0\>0 的边。由 PPP 的最短性可推出矛盾。因此 PPP 中的所有边都在 GfG\_fGf​ 中存在,但阻塞流增广后,至少有一条 GfG\_fGf​ 中的最短路径上的边被饱和,故 PPP 的长度必然大于 dk(t)d\_k(t)dk​(t)。证毕! 推论:Dinic 算法中 BFS 的次数不超过 ∣V∣\\lvert V\\rvert∣V∣,故总复杂度 O(∣V∣2∣E∣)O(\\lvert V\\rvert^2\\lvert E\\rvert)O(∣V∣2∣E∣)。 ## Part.6 Dinic 算法实践[#](#part6-dinic-算法实践) ### 当前弧优化[#](#当前弧优化) 代码中的 `cur[]` 实现了当前弧优化。其原理是:在 DFS 过程中,若某条边已被尝试且无法推送更多流量,则同一轮 BFS 分层中无需再次尝试,直接从下一条边开始。 ### 代码[#](#代码) ``` struct Edge { int to, weight, nxt; } edges[MAXM << 1]; int head[MAXN], ecnt = 2, n, m; void addedge(int u, int v, int weight) { edges[ecnt] = Edge{v, weight, head[u]}; head[u] = ecnt++; } int dep[MAXN], cur[MAXN], s, t; bool bfs() { clean(dep); queue < int > q; dep[s] = 1; q.psh(s); while (q.size()) { int u = q.front(); q.pop(); for (int i = head[u]; i; i = edges[i].nxt) { int v = edges[i].to; if (!dep[v] && edges[i].weight) { dep[v] = dep[u] + 1; q.psh(v); if (v == t) return true; } } } return false; } int dfs(int u, int flow) { if (u == t) return flow; int used = 0; for (int &i = cur[u]; i; i = edges[i].nxt) { int v = edges[i].to; if (dep[v] == dep[u] + 1 && edges[i].weight) { int res = dfs(v, min(flow - used, edges[i].weight)); if (res) { edges[i].weight -= res; edges[i ^ 1].weight += res; used += res; } if (used == flow) break; } } return used; } int dinic() { int mf = 0; while (bfs()) { memcpy(cur, head, sizeof cur); while (int res = dfs(s, inf)) mf += res; } return mf; } ``` cpp ## Part.7 HLPP(最高标号预流推进)算法[#](#part7-hlpp最高标号预流推进算法) ### 7.1 算法思想和基本概念[#](#71-算法思想和基本概念) HLPP(Highest-Label Preflow Push)与 Dinic 等增广路算法不同,采用预流推进的思路: 1. 不保持流量守恒:允许节点暂时存储超额流。 2. 高度函数:给每个节点一个高度,流只能从高处向低处推送。 3. 最高标号优先:每次选择高度最高的活跃节点处理。 定义超额流 e(u)e(u)e(u): e(u)\=∑vf(v,u)−∑vf(u,v)e(u) = \\sum\_{v} f(v,u) - \\sum\_{v} f(u,v)e(u)\=∑v​f(v,u)−∑v​f(u,v) - 当 e(u)\>0e(u) > 0e(u)\>0 时,uuu 称为**活跃节点** - 源点 sss 和汇点 ttt 除外 定义高度函数 h(u)h(u)h(u): - 流只能从高向低推:h(u)\=h(v)+1h(u) = h(v) + 1h(u)\=h(v)+1 - 初始高度:从 ttt 反向 BFS 得到,h(t)\=0h(t)=0h(t)\=0,h(s)\=nh(s)=nh(s)\=n ### 7.2 核心操作[#](#72-核心操作) 推流:当 e(u)\>0e(u) > 0e(u)\>0 且存在边 (u,v)(u,v)(u,v) 满足 r(u,v)\>0r(u,v) > 0r(u,v)\>0 且 h(u)\=h(v)+1h(u) = h(v) + 1h(u)\=h(v)+1 时,推送流量: δ\=min⁡(e(u),r(u,v))\\delta = \\min(e(u), r(u,v))δ\=min(e(u),r(u,v)) 重贴标签:当 e(u)\>0e(u) > 0e(u)\>0 但无可推流的邻居时,更新高度: h(u)\=min⁡{h(v)+1∣r(u,v)\>0}h(u) = \\min\\{h(v) + 1 \\mid r(u,v) > 0\\}h(u)\=min{h(v)+1∣r(u,v)\>0} ### 7.4 核心优化[#](#74-核心优化) - 最高标号优先:使用优先队列或桶维护活跃节点,每次取高度最大的处理。 - GAP 优化:若某个高度 kkk 的节点数为 0,则所有高度 \>k\>k\>k 的节点无法到达 ttt,直接将其高度设为 n+1n+1n+1。 - 当前弧优化:与 Dinic 相同,避免重复遍历已饱和的边。 ### 7.5 算法流程[#](#75-算法流程) ``` HLPP(s, t): 1. 反向 BFS 初始化高度 h,h[s] = n 2. 从 s 饱和推流,将活跃节点入桶 3. while mxh >= 0: u = 桶中最高高度的节点 for 当前弧遍历出边: if 边有残量 and h[u] == h[v] + 1: push(u, v) if e[u] == 0: break if e[u] > 0: relabel(u) 4. return e[t] ``` cpp ### 7.6 代码实现[#](#76-代码实现) ``` struct Edge { int to, nxt, cap; } edges[MAXM]; int head[MAXN], ecnt = 2, n, m; void addedge(int u, int v, int cap) { edges[ecnt] = {v, head[u], cap}, head[u] = ecnt++; edges[ecnt] = {u, head[v], 0}, head[v] = ecnt++; } int h[MAXN], eflow[MAXN], cur[MAXN], gap[MAXN << 1], mxh, s, t; vi bucket[MAXN << 1]; bool inq[MAXN]; void bfs() { memset(h, 0x3f, sizeof h); static int q[MAXN], qh, qt; h[t] = 0, q[qt = 0] = t, qh = 0, ++qt; while (qh < qt) { int u = q[qh++]; for (int i = head[u]; i; i = edges[i].nxt) { int v = edges[i].to; if (edges[i ^ 1].cap && h[v] > h[u] + 1) h[v] = h[u] + 1, q[qt++] = v; } } h[s] = n; } void push(int u) { for (int &i = cur[u]; i; i = edges[i].nxt) { int v = edges[i].to; if (edges[i].cap && h[u] == h[v] + 1) { int delta = min(eflow[u], edges[i].cap); if (!delta) continue; edges[i].cap -= delta, edges[i ^ 1].cap += delta; eflow[u] -= delta, eflow[v] += delta; if (v != s && v != t && !inq[v] && eflow[v]) inq[v] = true, bucket[h[v]].pb(v), mxh = max(mxh, h[v]); if (!eflow[u]) break; } } } void relabel(int u) { int mnh = inf; for (int i = head[u]; i; i = edges[i].nxt) if (edges[i].cap) mnh = min(mnh, h[edges[i].to]); int nwh = mnh + 1; if (!(--gap[h[u]]) && h[u] < n) { up(i, 1, n) if (i != s && i != t && h[i] > h[u] && h[i] <= n) h[i] = n + 1; up(i, h[u] + 1, n) { for (int v : bucket[i]) inq[v] = false; bucket[i].clear(); gap[n] += gap[i], gap[i] = 0; } } h[u] = nwh; if (nwh <= n) ++gap[nwh], bucket[nwh].pb(u), inq[u] = true, mxh = max(mxh, nwh); cur[u] = head[u]; } int hlpp() { if (s == t) return 0; bfs(); clean(gap), clean(eflow), clean(inq); up(i, 1, n) { if (h[i] < n) ++gap[h[i]]; else ++gap[n]; } for (int i = head[s]; i; i = edges[i].nxt) { int v = edges[i].to, cap = edges[i].cap; if (cap) { edges[i].cap -= cap, edges[i ^ 1].cap += cap; eflow[s] -= cap, eflow[v] += cap; if (v != t && eflow[v] && !inq[v] && h[v] < n) inq[v] = true, bucket[h[v]].pb(v), mxh = max(mxh, h[v]); } } while (mxh >= 0) { while (mxh >= 0 && bucket[mxh].empty()) --mxh; if (mxh < 0) break; int u = bucket[mxh].back(); bucket[mxh].ppb(); inq[u] = false; if (!eflow[u]) continue; if (!cur[u]) cur[u] = head[u]; push(u); if (eflow[u]) relabel(u); } return eflow[t]; } ``` cpp ## Part.8 题目选讲 A[#](#part8-题目选讲-a) ### [P3376 【模板】网络最大流 ↗](https://www.luogu.com.cn/problem/P3376) & [P4722 【模板】最大流 加强版 / 预流推进 ↗](https://www.luogu.com.cn/problem/P4722)[#](#p3376-模板网络最大流--p4722-模板最大流-加强版--预流推进) 模板题,代码见上。 ### [P2740 \[USACO4.2\] 草地排水 Drainage Ditches ↗](https://www.luogu.com.cn/problem/P2740)[#](#p2740-usaco42-草地排水-drainage-ditches) s\=1, t\=ns=1,\\ t=ns\=1, t\=n ### [P2936 \[USACO09JAN\] Total Flow S ↗](https://www.luogu.com.cn/problem/P2936)[#](#p2936-usaco09jan-total-flow-s) 换成字符。 ### [P1343 地震逃生 ↗](https://www.luogu.com.cn/problem/P1343)[#](#p1343-地震逃生) ans\=0ans=0ans\=0 特判。 ### [P3386 【模板】二分图最大匹配 ↗](https://www.luogu.com.cn/problem/P3386)[#](#p3386-模板二分图最大匹配) 构造: - 虚拟一个 sss,与左部所有点建边。 - 左右部建边。 - 虚拟一个 ttt,与右部所有点建边。 如图: ![1](https://cdn.luogu.com.cn/upload/image_hosting/u9ov9vcs.png) --- ## Vercel 仅部署指定分支的方法 URL: https://blog.rusin7.com/article/vercel-deploying-only-1-branch 如何指定特殊分支? 从中选择的项目,在侧边栏中打开Settings 2026/05/12 3 分钟 [git](/tags/git) # Vercel 仅部署指定分支的方法 > 如何指定特殊分支? 从中选择的项目,在侧边栏中打开Settings 次阅读 [| 次评论](#waline) ## 如何指定特殊分支[#](#如何指定特殊分支) 1. 从[仪表板 ↗](https://vercel.com/dashboard)中选择的项目 2. 在侧边栏中打开 Settings。 3. 点击 Environments。 4. 点击 Production 环境(/settings/environments/production)。 {% tip cogs %}这样配置之后,Vercel 仍然会在任一分支更改时自动构建,结果当然是 {% label Error red %} 了!怎么办呢?{% endtip %} ## 使用分支跟踪(推荐)[#](#使用分支跟踪推荐) 最直接的方法是在项目设置中配置分支跟踪。默认情况下,Vercel 会在所有分支上触发部署,但可以指定 {% label main red %} red %} 分支作为生产环境分支,这样只有 {% label main red %} 分支的变更才会触发生产部署。 开启分支跟踪非常简单,按照以下步骤操作: 1. 从[仪表板 ↗](https://vercel.com/dashboard)中选择的项目 2. 在侧边栏中打开 Settings。 3. 点击 Environments。 4. 点击 Production 环境(/settings/environments/production)。 5. 在 Branch Tracking 中,输入想要追踪的分支名称,例如 {% label main red %}。 6. 点击 `Save`。 还可以在 Preview 环境(/settings/environments/preview)中关闭 Branch Tracking。这样就可以确保只有 {% label main red %} 分支的变更才会触发任何构建。 ## 使用 git 配置[#](#使用-git-配置) 在项目根目录的 `vercel.json` 文件中添加 `git.deploymentEnabled` 配置,精确控制哪些分支可以触发部署: ``` { "git": { "deploymentEnabled": { "main": true } } } ``` json ## 使用忽略构建步骤[#](#使用忽略构建步骤) 如果需要更灵活的控制,可以在项目设置的“忽略构建步骤”部分使用自定义 Bash 脚本: ``` #!/bin/bash if [[ "$VERCEL_GIT_COMMIT_REF" == "main" ]]; then exit 1 # 继续构建 else exit 0 # 跳过构建 fi ``` bash --- ## 写作指南:Markdown / MDX URL: https://blog.rusin7.com/article/writing-markdown-mdx 主题内支持的 Markdown 扩展、数学公式、代码高亮与一些写作约定。 2026/01/11 / Update 2026/01/11 1 分钟 zh [markdown](/tags/markdown) # 写作指南:Markdown / MDX > 主题内支持的 Markdown 扩展、数学公式、代码高亮与一些写作约定。 次阅读 [| 次评论](#waline) ## 1\. Markdown 支持范围[#](#1-markdown-支持范围) 主题默认启用了常用扩展: - GFM:表格、删除线、任务列表等 - 数学公式:KaTeX(`$...$` / `$$...$$`) - 代码高亮:Shiki(支持标题、差异标注等) ## 2\. 数学公式(KaTeX)[#](#2-数学公式katex) 行内: ``` 欧拉公式:$e^{i\\pi}+1=0$ ``` md 块级: ``` $$ \\int_0^1 x^2 dx = \\frac{1}{3} $$ ``` md ## 3\. 代码块增强(差异/高亮)[#](#3-代码块增强差异高亮) 你可以在代码中使用注释标记来展示变更(示例来自主题的高亮 transformer): ``` const a = 1 const a = 2 ``` ts 也可以做行高亮: ``` const token = 'secret' ``` ts ## 4\. 什么时候用 MDX[#](#4-什么时候用-mdx) 当你需要在文章里使用组件(例如 `Aside`、`Tabs`、`GithubCard` 等)时,请使用 `.mdx`,并在文件顶部 `import` 组件。 组件用法示例文档:见 “MDX 组件使用”。 --- ## Astro-theme-cyanwind 使用文档 URL: https://blog.rusin7.com/collection/docs 主题配置、部署与写作指南(中英双语)。 ![Astro-theme-cyanwind 使用文档](https://picr2.axi404.top/1767811093734_image.webp) # Astro-theme-cyanwind 使用文档 主题配置、部署与写作指南(中英双语)。 - [2026/01/11 写作指南:Markdown / MDX 主题内支持的 Markdown 扩展、数学公式、代码高亮与一些写作约定。 1 分钟 zh ](/article/writing-markdown-mdx) - [ markdown ](/tags/markdown) - [2026/01/11 MDX 组件使用:User & Advanced 文章内组件(Aside/Tabs 等)与高级组件(LinkPreview/GithubCard 等)的使用方式。 1 分钟 zh ](/article/mdx-components) - [ markdown ](/tags/markdown) --- ## Archives URL: https://blog.rusin7.com/en/archives A list of all the years of creating my posts # Archives ## 2026 32 posts - [Sep 29, 2026 单源最短路算法 ](/en/article/shortest-path) - [Aug 31, 2026 Cyanwind 主题 markdown 语法 ](/en/article/how-to-use-markdown) - [Aug 13, 2026 Rusin note 项目推荐 ](/en/article/rusin-note) - [Jan 11, 2026 MDX 组件使用:User & Advanced ](/en/article/mdx-components) - [Jan 11, 2026 写作指南:Markdown / MDX ](/en/article/writing-markdown-mdx) - [Aug 11, 2026 在 VPS 上部署洛谷保存站 ](/en/article/deploy-lg-saver) - [Aug 3, 2026 博客迁移分流说明 ](/en/article/explanation-of-blog-migration) - [Jul 22, 2026 洛谷网校 CSP 初赛笔记 ](/en/article/luogu-class-csp-j-note) - [Jun 7, 2026 在 Hexo 中复现洛谷插件 ](/en/article/luogu-plugin-in-hexo) - [Jun 7, 2026 笔记——树形动态规划 ](/en/article/notes-of-dp-on-trees) - [Jun 6, 2026 题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ! ](/en/article/at-pakencamp-2020-day1-d-sol) - [Jun 6, 2026 AC 自动机笔记 ](/en/article/automated-ac) - [Jun 6, 2026 JC 提高班期末测试题解 ](/en/article/jc-the-end-of-class-test-solution) - [Jun 6, 2026 题解:P13361 \[GCJ 2011 Qualification\] Bot Trust ](/en/article/p13361-sol) - [Jun 6, 2026 题解:P8506 标题计数 ](/en/article/p8506-sol) - [Jun 6, 2026 题解:P8534 「Wdoi-2」比赤色更红的梦 ](/en/article/p8534-sol) - [Jun 6, 2026 网络流笔记 ](/en/article/the-network-flow-notes) - [May 14, 2026 拯救谷歌和 Github!你的新“自行车” ](/en/article/devsidecar) - [May 12, 2026 Vercel 仅部署指定分支的方法 ](/en/article/vercel-deploying-only-1-branch) - [Apr 20, 2026 对单一仓库配置小号以远程管理小号仓库 ](/en/article/configure-a-single-warehouse) - [Apr 19, 2026 在 VS code 上远程管理 Github 仓库并自动化部署项目 ](/en/article/remote-github-repo-on-vs-code) - [Apr 6, 2026 侧边栏添加个性定位欢迎信息 ](/en/article/location-welcome-information) - [Apr 3, 2026 第22届浙大宁波理工学院程序设计大赛题解 ](/en/article/22nd-zhejiang-competition-solution) - [Apr 3, 2026 在 arm64 中安装虚拟环境 ](/en/article/arm64-install-base) - [Apr 3, 2026 图论之欧拉回路、差分约束——算法笔记 ](/en/article/euro-circuit-notes) - [Apr 3, 2026 题解:P14702 \[ICPC 2024 Tehran R\] Boat ](/en/article/p14702-sol) - [Apr 3, 2026 题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree ](/en/article/p14731-sol) - [Apr 3, 2026 我常常追忆过去 ](/en/article/remember-the-past) - [Mar 30, 2026 题解:AT\_joi2024\_yo1c\_b 桁 (Digit) ](/en/article/at-joi2024) - [Mar 30, 2026 题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type ](/en/article/p14730-sol) - [Mar 23, 2026 题解:CF2139B Cake Collection ](/en/article/cf2139b-sol) - [Mar 23, 2026 免费获取二级域名并部署 github 仓库 ](/en/article/free-domain) --- ## 第22届浙大宁波理工学院程序设计大赛题解 URL: https://blog.rusin7.com/en/article/22nd-zhejiang-competition-solution 本文讲述了第22届浙大宁波理工学院程序设计大赛的 C++ 代码。 ![第22届浙大宁波理工学院程序设计大赛题解](https://image.rusin7.com/file/hexo/cover/VdGvvMhu.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/VdGvvMhu.webp) Apr 3, 2026 15 分钟 [题解](/tags/题解) / [比赛](/tags/比赛) # 第22届浙大宁波理工学院程序设计大赛题解 > 本文讲述了第22届浙大宁波理工学院程序设计大赛的 C++ 代码。 views [| comments](#waline) ## A. 字符串[#](#a-字符串) 按照题意模拟即可,如果想要省掉代码量可以开个 `std::vector> ve(n)` 前一个记录字符,后一个记录当前的下标,直接进行升序排序,然后直接从k+1个开始输出。 提供排序的代码。 ``` void clearlove13(void){ int n, k; std::cin >> n >> k; std::string s; std::cin >> s; std::vector> ve(n); for (int i = 0; i < n; i++) { ve[i] = std::make_pair(s[i], i); } std::sort(ve.begin(), ve.end()); std::vector> ans; ans.reserve(n); for (int i = k; i < n; i++) { ans.push_back({ve[i].first, ve[i].second}); } std::sort(ans.begin(), ans.end(), [&](auto & a, auto & b) { return a.second < b.second; }); for (auto &[x, y] : ans) { std::cout << x; } } ``` cpp ## B. 价格跨度[#](#b-价格跨度) 题意大概就是求该 aia\_iai​ 前面第一个大于该 aia\_iai​ 的位置,从题目数据可得知,此题我们需要使用 O(n)\\mathcal{O(n)}O(n) 复杂度来写这道题,思考一下可以使用单调栈来实现,只需要等效思想来写即可。 ``` void clearlove13(void) { int n; std::cin >> n; std::vector a(n + 1); for (int i = 1; i <= n; i++) { std::cin >> a[i]; } std::vectorst; std::vector ans(n + 1); st.reserve(n + 1); for (int i = 1; i <= n; i++) { while (!st.empty() && a[st.back()] <= a[i]) { st.pop_back(); } if (st.empty()) { ans[i] = i; } else { ans[i] = i - st.back(); } st.push_back(i); } for (int i = 1; i <= n; i++) { std::cout << ans[i]; if (i != n) std::cout << ' '; } } ``` cpp ## C. 斐波那契数[#](#c-斐波那契数) 事实上题目已经告诉你了做法直接模拟即可。 ``` i64 a[51]; void clearlove13(void) { int n; std::cin >> n; std::cout << a[n] << '\n'; } int main(void) { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); a[1] = 1; a[0] = 1; for (int i = 2; i <= 50; i++) { a[i] = a[i - 1] + a[i - 2]; } int cas = 1; std::cin >> cas; while (cas--) clearlove13(); return 0; } ``` cpp ## D. 回收礼物[#](#d-回收礼物) 设 f(x→y)f(x\\to y)f(x→y) 是以 111 为根 ,求x到y的树上最小路径 我们先了解题意,就可以明白是需要求形如 f(1→2)+f(2→3)+f(3→…)+f(…→2)f(1\\to 2)+f(2\\to 3)+f(3\\to \_{\\dots})+f(\_{\\dots}\\to 2)f(1→2)+f(2→3)+f(3→…​)+f(…​→2) 这么一个式子,那么我们应该怎么快速去求树上最短路径呢?引入lca求最近公共祖先,有一个小trick就是我们 所以我们就先求出到两个点的深度之和再减去公共祖先的深度就可以写出这道题了。 ``` struct LCA { int n, lg; std::vector> up; std::vector depth, tin, tout; int timer = 0; LCA(std::vector>& ed, int root = 0) { n = int(ed.size()); lg = std::__lg(n) + 1; up.assign(n, std::vector(lg)); depth.assign(n, 0); tin.resize(n), tout.resize(n); auto dfs = [&](auto self, int u, int p) -> void { tin[u] = timer++; up[u][0] = p; for (int i = 1; i < lg; ++i) up[u][i] = up[up[u][i - 1]][i - 1]; for (int v : ed[u]) { if (v == p) continue; depth[v] = depth[u] + 1; self(self, v, u); } tout[u] = timer++; }; dfs(dfs, root, root); } bool is_ancestor(int u, int v) { return tin[u] <= tin[v] && tout[v] <= tout[u]; } int get_lca(int u, int v) { if (is_ancestor(u, v)) return u; if (is_ancestor(v, u)) return v; for (int i = lg - 1; i >= 0; --i) if (!is_ancestor(up[u][i], v)) u = up[u][i]; return up[u][0]; } std::vector get_path(int u, int v) { int w = get_lca(u, v); std::vector up_path, down_path; while (u != w) { up_path.push_back(u); u = up[u][0]; } up_path.push_back(w); while (v != w) { down_path.push_back(v); v = up[v][0]; } std::reverse(down_path.begin(), down_path.end()); up_path.insert(up_path.end(), down_path.begin(), down_path.end()); return up_path; } }; void clearlove13() { constexpr int lg = 20; int n, q, rt; std::cin >> n >> q ; rt = 1; std::vector> g(n + 1); std::vectorch(q); for (int i = 2; i <= n; i++) { int u; std::cin >> u; g[u].push_back(i); g[i].push_back(u); } std::vector dep(n + 1); std::vector> up(n + 1); for (int i = 1; i <= n; i++) { std::fill(up[i].begin(), up[i].end(), -1); } auto dfs = [&](auto self, int u, int fa) -> void { up[u][0] = fa; for (int i = 1; i < lg; i++) { if (up[u][i - 1] != -1) { up[u][i] = up[up[u][i - 1]][i - 1]; } } for (int v : g[u]) { if (v != fa) { dep[v] = dep[u] + 1; self(self, v, u); } } }; dfs(dfs, rt, -1); auto lca = [&](i64 u, i64 v) -> int { if (dep[u] < dep[v]) std::swap(u, v); i64 d = dep[u] - dep[v]; for (int i = 0; i < lg; i++) { if (d >> i & 1) u = up[u][i]; } if (u == v) return u; for (int i = lg - 1; i >= 0; i--) { if (up[u][i] != up[v][i]) { u = up[u][i]; v = up[v][i]; } } return up[u][0]; }; auto dist = [&](i64 u, i64 v) -> int { i64 l = lca(u, v); return dep[u] + dep[v] - 2 * dep[l]; }; for (auto &i : ch) { std::cin >> i; } i64 ans = dist(1, ch[0]); for (int i = 1; i < q; i++) { ans += dist(ch[i - 1], ch[i]); } std::cout << ans << '\n'; } ``` cpp ## E. 我们都是小怪兽 (Rescue Qfish)[#](#e-我们都是小怪兽-rescue-qfish) 推导公式发现边权每 444 步循环。利用分层图思想,将每个点按时刻拆为 444 层,层间连边,跑 Dijkstra 最短路即可。提供建图的代码。 ``` for (ll i = 1; i <= m; i++) { cin >> u >> v >> w; ll w0 = w; //第一层是L ll w1 = (w - 1) * quickpow(w + 1, md - 2, md) % md; //第二层是(L-1)/(L+1) ll w2 = -quickpow(w, md - 2, md) % md; //第三层是(-1)/L ll w3 = (w + 1) * quickpow((1 - w + md) % md, md - 2, md) % md;//第四层是(L+1)/(1-L) 每四次循环 if (w1 < 0) w1 += md; if (w2 < 0) w2 += md; if (w3 < 0) w3 += md; g[u].push_back({w0, v + n}); g[v].push_back({w0, u + n}); g[u + n].push_back({w1, v + 2 * n}); g[v + n].push_back({w1, u + 2 * n}); g[u + 2 * n].push_back({w2, v + 3 * n}); g[v + 2 * n].push_back({w2, u + 3 * n}); g[u + 3 * n].push_back({w3, v}); g[v + 3 * n].push_back({w3, u}); } ``` cpp ## F. 爱的魔力转圈圈——终极幸存者挑战赛[#](#f-爱的魔力转圈圈终极幸存者挑战赛) 这是一道约瑟夫环问题,但是数据开小了遍历也能过,递推公式: f(n,k)\=f(n−1,k)+k\\mathcal{f(n, k)=f(n-1, k)+k}f(n,k)\=f(n−1,k)+k ``` #include using namespace std; int main() { int n; long long k; cin >> n >> k; long long res = 0; // f(1)=0(1个人时位置为0) for (int i = 2; i <= n; ++i) { res = (res + k) % i; // 递推计算f(i) } cout << res + 1 << endl; // 转换为1-based编号 return 0; } ``` cpp ## G. 探险者的补给路线[#](#g-探险者的补给路线) 直接根据题目意思写就行,x,yx, yx,y 分别是 a,ba, ba,b 的倍数。 ``` void clearlove13(void) { i64 a, b, x, y; std::cin >> a >> b >> x >> y; if (x % a == 0 && y % b == 0 && x >= 0 && y >= 0) { std::cout << "YES\n"; } else { std::cout << "NO\n"; } } ``` cpp ## H. Qfish的法术[#](#h-qfish的法术) 首先我们根据题意每次加2,可以知道区间和无论怎么操作奇偶性永远不会改变,由此延申我们进行分类讨论,如果区间长度是奇数的话,经过操作后的区间和直接贪心成偶数的目标去,因没有要求对操作后的值有具体要求,所以区间长度是奇数就一定可以,如果区间长度为偶数,但区间和为奇数,每次+2并不会改变奇偶性,所以无解。 值得注意的是,我们需要对长度为2的区间进行一个简单的特判,区间和直接用前缀和维护就行。 ``` void clearlove13(void) { int n, t; std::cin >> n >> t; std::vectora(n + 1); for (int i = 1; i <= n; i++) { std::cin >> a[i]; a[i] += a[i - 1]; } while (t--) { int l, r; std::cin >> l >> r; if (r - l + 1 == 2 && (a[r] != a[l - 1])) { std::cout << "NO\n"; continue; } if (((r - l + 1LL) % 2 == 0) && ((a[r] - a[l - 1]) % 2 == 1)) { std::cout << "NO\n"; } else { std::cout << "YES\n"; } } } ``` cpp ## I. 字母混淆[#](#i-字母混淆) 直接根据题目来模拟就行。 ``` void solve(){ string s; int n; cin >> n >> s; s = " " + s; for (int i = 1; i <= n; ++i) cout << (char)((s[i] + 32 - 'a' - 2 + 26) % 26 + 'a'); } ``` cpp ## J. 小s的杀戮尖塔[#](#j-小s的杀戮尖塔) 超级大模拟, 首先我们可以观察到,观者的血量不会超过1000,并且大鄂虫每行动3轮攻击力就会永久增加,而观者每轮理想情况下只能有15点格挡。所以计算可知游戏轮数一定不会超过60轮。因此可以使用三维 dpdpdp 求解。dpi,j,qdp\_{i, j, q}dpi,j,q​,iii 代表第 iii 轮,jjj 代表大鄂虫剩余 jjj 滴血,qqq 代表观者处于的姿态。记录的是观者剩余的血量。每次抽取 555 张牌,用 dfs 记录所有会到达的状态。后面就是漫长的调试代码时间,总复杂度是 O(60×b×3×5)\\mathcal{O(60\\times b \\times 3 \\times 5)}O(60×b×3×5)。而且题目的伤害与大鄂虫的格挡实际上都是3的倍数,因此可以把伤害与血量 ÷3\\div 3÷3 进行计算。实际上由于状态数远不会到达最高复杂度,因此代码可以通过。std 的耗时约 150ms150ms150ms。 一些容易导致 WA 的细节: - 第一轮的行动 111 与后面轮次的行动 111 不同。后面轮次的行动 111 是有 999 点护甲的,第一轮没有。 - 最后 111 轮观者战胜大鄂虫时,游戏立即结算,此时观者不会再受到伤害。 - 把费用用完并不是最优解,例如手里是 555 张暴怒,此时可能会选择一张都不打。 由于出题人的 std 过于臃肿,因此在这里放上能够通过对拍的 AI 代码。 ``` typedef long long ll; ll dp[2][40400][3]; ll num[505050]; struct MoveResult { ll dmg; // 造成的伤害 ll self_blk; // 获得的格挡 ll end_stance; // 结束姿态 }; vector moves_cache[3]; // [起始姿态] -> 结果列表 int main(){ cin.tie(0); cout.tie(0); ios::sync_with_stdio(0); ll t, a, b, n; if(!(cin >> t)) return 0; while(t--){ cin >> a >> b >> n; for(int i=1; i<=n; i++) cin >> num[i]; // 压缩敌方血量 ll max_b = (b - 1) / 3 + 1; for(int x=0; x<=max_b; x++) for(int s=0; s<3; s++) dp[0][x][s] = -1; vector> q; // 队列: {敌方血量, 姿态} q.push_back({max_b, 0}); dp[0][max_b][0] = a; ll ans = -1; ll turn = 0; ll gong = 0; // 力量 while(!q.empty() && turn < 60) { ll cur = turn % 2; ll nxt = (turn + 1) % 2; turn++; // 重置下一轮DP状态 for(int x=0; x<=max_b; x++) for(int s=0; s<3; s++) dp[nxt][x][s] = -1; // 1. 确定手牌 vector hand; for(int i=0; i<5; i++) { ll idx = ((turn - 1) * 5 + i) % n + 1; hand.push_back(num[idx]); } sort(hand.begin(), hand.end()); // 2. 预计算所有出牌结果 for(int s=0; s<3; s++) moves_cache[s].clear(); do { for(int start_s=0; start_s<3; start_s++) { ll c = 3, cur_s = start_s; ll raw_dmg = 0, self_blk = 0; // 记录"一张牌都不出"也是一种可能 moves_cache[start_s].push_back({0, 0, start_s}); for(ll card : hand) { ll cost = (card >= 4) ? 2 : 1; if(c < cost) break; c -= cost; // 伤害计算 ll d = 0; if(card == 1) d = 6; else if(card == 3 || card == 4) d = 9; if(cur_s == 1) d *= 2; // 愤怒翻倍 raw_dmg += d; // 格挡计算 if(card == 2) self_blk += 5; else if(card == 5) self_blk += 8; // 姿态变更 ll old_s = cur_s; if(card == 3) cur_s = 0; else if(card == 4) cur_s = 1; else if(card == 5) cur_s = 2; if(old_s == 2 && (card == 3 || card == 4)) c += 2; // 存入结果 (伤害/3, 格挡, 姿态) moves_cache[start_s].push_back({raw_dmg / 3, self_blk, cur_s}); } } } while(next_permutation(hand.begin(), hand.end())); // 3. 大鄂虫属性计算 ll chong = (turn - 1) % 3 + 1; if(turn > 1 && (turn - 1) % 3 == 0) gong += 5; // 每3回合加一次力量 ll enemy_dmg = 0; if(chong == 1) enemy_dmg = 12 + gong; else if(chong == 2) enemy_dmg = 7 + gong; ll enemy_blk_reduce = 0; if(turn > 1) { ll prev_act = (turn - 2) % 3 + 1; if(prev_act == 2) enemy_blk_reduce = 2; // 6/3 else if(prev_act == 3) enemy_blk_reduce = 3; // 9/3 } vector> next_q; // 4. 状态转移 for(auto &st : q) { ll e_hp = st.first; ll p_stance = st.second; ll p_hp = dp[cur][e_hp][p_stance]; for(auto &res : moves_cache[p_stance]) { // 计算实际对敌伤害 ll dmg_dealt = max(0LL, res.dmg - enemy_blk_reduce); ll next_e_hp = e_hp - dmg_dealt; // 击杀判定 if(next_e_hp <= 0) { ans = max(ans, p_hp); continue; // 敌死,不入队 } // 玩家承伤计算 ll incoming = enemy_dmg; if(res.end_stance == 1) incoming *= 2; // 愤怒易伤 ll take = max(0LL, incoming - res.self_blk); ll next_p_hp = p_hp - take; if(next_p_hp > 0) { if(dp[nxt][next_e_hp][res.end_stance] == -1) { next_q.push_back({next_e_hp, res.end_stance}); dp[nxt][next_e_hp][res.end_stance] = next_p_hp; } else { dp[nxt][next_e_hp][res.end_stance] = max(dp[nxt][next_e_hp][res.end_stance], next_p_hp); } } } } q = next_q; } cout << ans << "\n"; } return 0; } ``` cpp --- ## 在 arm64 中安装虚拟环境 URL: https://blog.rusin7.com/en/article/arm64-install-base 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 ![在 arm64 中安装虚拟环境](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) Apr 3, 2026 3 分钟 [git](/tags/git) / [nodejs](/tags/nodejs) / [教程](/tags/教程) # 在 arm64 中安装虚拟环境 > 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 views [| comments](#waline) ## 安装虚拟环境[#](#安装虚拟环境) ### 下载[#](#下载) 下载指定版本: ``` wget https://repo.anaconda.com/miniconda/Miniconda3-py312_24.7.1-0-Linux-aarch64.sh ``` bash 如果官方源下载缓慢,可以试试**国内的清华镜像源**: ``` wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py312_24.7.1-0-Linux-aarch64.sh ``` bash 运行安装脚本: ``` bash Miniconda3-py312_24.7.1-0-Linux-aarch64.sh ``` bash 安装过程中,按照提示操作即可: - 按 `Enter` 键阅读完许可协议。 - 输入 `yes` 接受协议。 - 按 `Enter` 键接受默认安装路径(`/home/user/miniconda3`)。 - **关键一步**:按 Enter 后,安装程序会开始解压文件,然后在接近结束时,一定会问你一个问题,类似: ``` Do you wish the installer to initialize Miniconda3 by running conda init? [yes|no] ``` text 这是问你是否要初始化 Conda 时,务必输入 `yes` 并回车。 重新加载配置文件: ``` source ~/.bashrc ``` bash ### 验证[#](#验证) **重新打开**终端,你会看到终端提示符前面出现了 (base),这就表示安装成功了! ## 安装 Git[#](#安装-git) ``` conda install git ``` bash ### 验证 Git 安装[#](#验证-git-安装) 安装成功后,再次检查 Git 版本: ``` git --version ``` bash 如果输出类似 `git version 2.x.x`,就表示安装成功了。 ### 让 VS Code 识别 Git[#](#让-vs-code-识别-git) ``` which git ``` bash 记下输出。 操作方法: 1. 在 VS Code 中按 `Ctrl + ,` 打开设置。 2. 在搜索框输入 `git.path`。 3. 找到 **“在 settings.json 中编辑”**(点击右上角的文档图标)。 4. 在 JSON 配置中添加(或修改): ``` "git.path": "刚刚的输出" ``` json 5. 保存文件,**关闭 VS Code 再重新打开**。 ## 安装 NodeJs[#](#安装-nodejs) ### 安装 nvm[#](#安装-nvm) 运行以下代码(也可以自己从 [NodeJs 官网 ↗](https://nodejs.org/zh-cn/download) 获得) ``` curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash ``` bash 然后关闭再重新打开一个终端。 ### 安装 Node.js[#](#安装-nodejs-1) 加载后,就可以使用 nvm 安装 Node.js 了。推荐以下两种方式: 1. LTS(长期支持)版本 ``` nvm install --lts ``` bash 2. 安装最新的稳定版本 ``` nvm install node ``` bash 最后输入 ``` npm install -g pnpm npm install -g yarn ``` bash ### 验证[#](#验证-1) ``` npm -v pnpm -v yarn -v ``` bash --- ## 题解:AT_joi2024_yo1c_b 桁 (Digit) URL: https://blog.rusin7.com/en/article/at-joi2024 本文讲述了如何使用 C++ 完成洛谷的 AT_joi2024_yo1c_b 桁 (Digit),思路清晰、排版精美 ![题解:AT\_joi2024\_yo1c\_b 桁 (Digit)](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 30, 2026 1 分钟 [题解](/tags/题解) / [c++](/tags/c++) # 题解:AT\_joi2024\_yo1c\_b 桁 (Digit) > 本文讲述了如何使用 C++ 完成洛谷的 AT\_joi2024\_yo1c\_b 桁 (Digit),思路清晰、排版精美 views [| comments](#waline) [**安利一下自己的博客** ↗](http://blog.rusin7.com "博客") [题目传送门 ↗](https://www.luogu.com.cn/problem/AT_joi2024_yo1c_b "题目传送门") ## 题目大意[#](#题目大意) 给出 a,ba,ba,b,求 a+ba+ba+b 的位数。 ## 思路引导[#](#思路引导) 提问 如何统计 a+ba+ba+b 的位数? 成功 我们将 a+ba+ba+b 转化为字符串函数大法好,输出 a+ba+ba+b 的长度即可。 ## 核心代码[#](#核心代码) ``` #include using namespace std; int a,b; int main() { cin>>a>>b; cout< 本文讲述了如何使用 C++ 完成洛谷的 AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!,思路清晰、排版精美 views [| comments](#waline) ## 问题分析[#](#问题分析) 题目要求计算边长为 NNN 的立方体被平面 x+y+z\=Kx+y+z=Kx+y+z\=K 切割后,包含原点 (0,0,0)(0,0,0)(0,0,0) 的部分体积的 **6 倍**是多少。 立方体的范围为 0≤x,y,z≤N0 \\le x,y,z \\le N0≤x,y,z≤N,平面 x+y+z\=Kx+y+z=Kx+y+z\=K 将空间分为两部分,并且**包含原点的部分**满足 x+y+z≤Kx+y+z \\le Kx+y+z≤K。 ## 核心思路[#](#核心思路) 根据 KKK 与立方体的位置关系,平面切割立方体的效果不同,需分类讨论: - **平面在立方体外部(K≤0K \\le 0K≤0)**:如图 1 ,此时 x+y+z≤Kx+y+z \\le Kx+y+z≤K 不包含立方体任何部分,V立\=0V\_立=0V立​\=0。 ![1](https://cdn.luogu.com.cn/upload/image_hosting/2gwzloc6.png)图1\\tiny\\color{000000}图 1图1 - **平面切割出小四面体(03NK > 3NK\>3N)**:如图 5 ,整个立方体都满足 x+y+z≤Kx+y+z \\le Kx+y+z≤K,V立\=V\_立=V立​\= 立方体体积公式。 ![1](https://cdn.luogu.com.cn/upload/image_hosting/pid9y8n6.png) 图5\\tiny\\color{000000}图 5图5 ## 公式推导[#](#公式推导) - **当 K≤0K \\le 0K≤0** 此时 x+y+z≤Kx+y+z \\le Kx+y+z≤K 无立方体部分,6 倍体积为: > 6×0\=06 \\times 0=06×0\=0 - **当 0 K3K^3K3 - **当 N 3K2N−3KN2+N3−2(K−N)33K^2N - 3KN^2 + N^3 - 2(K - N)^33K2N−3KN2+N3−2(K−N)3 - 当 2N 6N3−(3N−K)36N^3 - (3N - K)^36N3−(3N−K)3 - **当 K\>3NK > 3NK\>3N** 整个立方体都满足 x+y+z≤Kx + y + z \\le Kx+y+z≤K,6 倍体积为立方体体积的 6 倍: > 6N36N^36N3 ## 代码实现[#](#代码实现) 根据上述推导,分情况计算结果: ``` #include using namespace std; long long n,k,res; int main(){ cin>>n>>k; if(k==0){ res=0; }else if(k<=n){ res=k*k*k; }else if(k<=2*n){ res=3*k*k*n-3*k*n*n+n*n*n-2*(k-n)*(k-n)*(k-n); }else if(k<=3*n){ res=6*n*n*n-(3*n-k)*(3*n-k)*(3*n-k); }else{ res=6*n*n*n; } cout< AC 自动机笔记 views [| comments](#waline) ![洛谷炸了](https://cdn.luogu.com.cn/upload/image_hosting/ycm2f9av.png) ![洛谷炸了](https://cdn.luogu.com.cn/upload/image_hosting/akus9280.png) ![洛谷炸了](https://cdn.luogu.com.cn/upload/image_hosting/rktfergq.png) 模板代码([P3808 AC 自动机(简单版) ↗](https://www.luogu.com.cn/problem/P3808)) ``` #include using namespace std; int n,tot,cnt[1000005],ch[1000005][30],ne[1000005]; void insert(string s){ int u=0; for(char c:s){ int v=c-'a'; if(!ch[u][v])ch[u][v]=++tot; u=ch[u][v]; } cnt[u]++; } void build(){ queueq; for(int i=0;i<26;++i){ if(ch[0][i])q.push(ch[0][i]); } while(!q.empty()){ int u=q.front(); q.pop(); for(int i=0;i<26;++i){ int v=ch[u][i]; if(v)ne[v]=ch[ne[u]][i],q.push(v); else ch[u][i]=ch[ne[u]][i]; } } } int query(string s){ int ans=0; for(int k=0,i=0;s[k];k++){ i=ch[i][s[k]-'a']; for(int j=i;j&&~cnt[j];j=ne[j]){ ans+=cnt[j],cnt[j]=-1; } } return ans; } string t; int main(){ cin>>n; for(int i=1;i<=n;++i){ string s; cin>>s; insert(s); } cin>>t; build(); cout< 本文讲述了如何使用 C++ 完成洛谷的 CF2139B Cake Collection,思路清晰、排版精美 views [| comments](#waline) [CF2139B Cake Collection ↗](https://www.luogu.com.cn/problem/CF2139B "CF2139B Cake Collection") [**安利一下**博客 ↗](https://blog.rusin7.com/ "博客 🥳🎆🎉祝大家 2026 新年快乐")🥳🎆🎉祝大家 2026 新年快乐! [纯享阅读区 ↗](https://www.luogu.com.cn/article/odez28v6 "纯享阅读区") ## 题意分析[#](#题意分析) **核心**:用 mmm 秒去拿 nnn 个烤好的蛋糕,要拿的尽量多。用 [贪心 ↗](https://oi-wiki.org/basic/greedy/ "贪心") 算法。 ## 思路引导[#](#思路引导) 提问 如何保证能选到最好的方案? 成功 对数组 aaa 从大到小进行排序,如果 n≤mn \\le mn≤m,则可以把所有烤箱中的蛋糕都拿一遍,生产蛋糕越多的**越晚拿**,且后面会给出证明:早拿一次再晚拿一次和直接晚拿一次一样,不如直接晚拿一次简单。否则 n\>mn>mn\>m,就直接拿排序后**最好**(aia\_iai​ 较大)的烤箱中的蛋糕,同样,生产蛋糕越多的**越晚拿**。 综上,取个 min⁡{n,m}\\min \\{n,m\\}min{n,m} 即可。 Tip 从大到小进行排序不用手写 `cmp` 了!使用 `greater()` 可以直接大到小进行排序。 示例代码: ``` sort(a+1,a+n+1,greater());//对数组 a 从大到小进行排序 ``` cpp 提问 如何证明早拿一次再晚拿一次同一个烤箱,和直接晚拿一次一样? 成功 **证明**: 设早拿的时间为 p1p\_1p1​,晚拿的时间为 p2p\_2p2​,烤箱每秒生成 aia\_iai​ 个蛋糕,早拿一次再晚拿一次可以拿走 p1×ai+(p2−p1)×ai\=p2×aip\_1 \\times a\_i+(p\_2-p\_1) \\times a\_i=p\_2 \\times a\_ip1​×ai​+(p2​−p1​)×ai​\=p2​×ai​,晚拿一次可以拿走 p2×aip\_2 \\times a\_ip2​×ai​,两式相等,故结论成立。 提问 每拿一次可以获得多少蛋糕? 成功 由于生产蛋糕越多的**越晚拿**,但我们已经从大到小排序了,循环的时间却是从小到大,应该用 m−i+1m-i+1m−i+1 才能让下标 iii 越小,生产蛋糕 aia\_iai​ 越多,时间 m−i+1m-i+1m−i+1 越大。 因此得出 aia\_iai​ 的价值为 (m−i+1)×ai(m-i+1)\\times a\_i(m−i+1)×ai​。 警告 不开 `long long` 见祖宗,不用 `1LL` 乘见祖宗。 ## 完整代码[#](#完整代码) ``` #include using namespace std; long long t,n,m,a[200005],s; int main(){ cin>>t; while(t--){ s=0; cin>>n>>m; for(int i=1;i<=n;i++)cin>>a[i]; sort(a+1,a+n+1,greater()); for(int i=1;i<=min(n,m);i++)s+=1LL*(m-i+1)*a[i]; cout<) / [git](/tags/git) # 对单一仓库配置小号以远程管理小号仓库 > 命令行操作给这个仓库单独设置小号仅本地生效把远程地址绑定到小 views [| comments](#waline) ## 命令行操作[#](#命令行操作) - 给这个仓库单独设置小号(仅本地生效) ``` git config --local user.name "用户名" git config --local user.email "邮箱" ``` bash - 把远程地址绑定到小号仓库 ``` git remote set-url origin https://github.com/用户名/仓库名.git ``` bash - 推送(第一次会让你登录小号) ``` git push -f origin main ``` bash ## 登录时怎么填?[#](#登录时怎么填) 弹出窗口时: **使用 SSH 登录** 在输入框中填入在 [这里 ↗](https://github.com/settings/tokens/new) 创建的 SSH 密钥(权限建议仅 Repo)。 * * * > ## 最终效果(最舒服的状态)[#](#最终效果最舒服的状态) > > - 全局 Git = 大号 > - 其他所有仓库 = 大号 > - 只有特定文件夹 = 小号 {% note blue ‘anzhiyufont anzhiyu-icon-bullhorn’ modern %}永远不用再切换账号{% endnote %} --- ## 在 VPS 上部署洛谷保存站 URL: https://blog.rusin7.com/en/article/deploy-lg-saver 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) ![在 VPS 上部署洛谷保存站](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) Aug 11, 2026 8 分钟 [云服务器](/tags/云服务器) / [建站](/tags/建站) / [教程](/tags/教程) # 在 VPS 上部署洛谷保存站 > 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) views [| comments](#waline) ## 项目地址[#](#项目地址) [Demo ↗](https://luogu.rusin7.com/) [https://luogu.rusin7.com/](https://luogu.rusin7.com/) [ laikit-dev / luogu-saver Waiting for api.github.com... ??? ??? ??? ????? ](https://github.com/laikit-dev/luogu-saver) ## 前置要求[#](#前置要求) 在开始之前,请确保你已具备以下条件: - 有一个邮箱或 Github、Google 账号。 - 有一定的 Linux 终端操作能力和 Web 知识。 - 能支付一个月 333 美元的费用或已经有服务器了。 ## 购买 VPS(如果你有服务器可以忽略)[#](#购买-vps如果你有服务器可以忽略) 进入 [Zeabur 注册 ↗](https://zeabur.cn/zh-CN/login),然后选一种方式注册,进入仪表盘后点击左侧“服务器”,然后点击“创建服务器”,选择“服务器-单机部署”,再选择“从 zeabur 购买服务器”,点击“前往购买”。 ![1](https://image.rusin7.com/file/uvHywUpv.png) 供应商选择 Tencent,方案中区域:`亚洲`,排序:`价格 ↑`,在前 444 个价格为 333 美元的服务器选一个。操作系统选 ZeaburOS,然后前往结账. ![2](https://image.rusin7.com/file/Zw5chk7S.png) 勾选 `我已阅读并同意上述重要事项······`,点击“设置付款方式”,选“充值余额”,然后用支付宝或微信支付充值到账户里。支付后,满屏的烟花会庆祝你的成功,然后你的服务器将会安装一系列自带的 Zeabur 服务。 ![3](https://image.rusin7.com/file/y2hhrecN.png) 到此,服务器就购买成功了! ### SSH 服务器[#](#ssh-服务器) 回到 Zeabur 首页,点击服务器、你的服务器名字进入详细页面,点击服务器运行信息中的 IPv4 旁边的一串 IP 地址复制下来,打开终端,输入以下内容: ``` ssh ubuntu@ ``` bash 如果输出 `ubuntu@'s password:`,那么没有问题,先不要关闭终端。 然后回到 Zeabur 服务器页面,点击上侧的 `SSH`,点击 SSH 密码下面的“···”(**不是“连接”**),此时可能会弹出警告,大致意思是“如果你在 ssh 后一不小心弄坏(`rm -rf`)了服务器,他们无法回复,只能重装系统”,不必理会,直接点“确定放弃权利”,然后点击密码复制到剪贴板,再回到终端,粘贴密码(粘贴时不会有 `*` 等字符出现,属于正常现象),让后 `Enter`,第一次 SSH 有交互式提问,输入 `y` 即可。如果终端输出类似如下,那么就成功了! ``` Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-124-generic x86_64) ··· ``` bash ## 部署保存站[#](#部署保存站) ### 部署基础设施 (数据库、缓存等)[#](#部署基础设施-数据库缓存等) 克隆项目仓库并进入目录: ``` git clone https://github.com/laikit-dev/luogu-saver.git cd luogu-saver ``` bash 编辑 docker-compose.yml 中密码: ``` nano docker-compose.yml ``` bash 用上、下键移动光标找到 `services.db.environment.MARIADB_ROOT_PASSWORD` 并修改为自己的密码,例:`MARIADB_ROOT_PASSWORD: 123456`。再找到 `services.meilisearch.environment.MEILI_MASTER_KEY` 并修改为自己的密码,例:`MEILI_MASTER_KEY: 123456`。然后按 `Ctrl + O , Enter`(字母 `O`,不是 000),最后按 `Ctrl + X` 退出。 然后启动基础设施服务: ``` sudo docker compose up -d ``` bash ### 构建项目[#](#构建项目) #### 升级 Node.js[#](#升级-nodejs) 由于默认 Node.js 版本过低(v18.19.1)而项目要求的 Node.js 版本是 22.18.0 或更高(见 README),Vite 也要求 20.19+ 或 22.12+。需要升级 Node.js。 安装 nvm ``` curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash source ~/.bashrc ``` bash 安装并切换到 Node.js 22 ``` nvm install 22 nvm alias default 22 nvm use 22 ``` bash 验证一下: ``` node -v ``` bash 应该显示 `v22.x.x`。 #### 开始构建[#](#开始构建) ``` npm install npm run build export VITE_API_URL=http://你的域名 # 替换为你的自定义域名 cd ~/luogu-saver/packages/backend npm install --production --ignore-scripts ``` bash #### 安装依赖、创建数据库[#](#安装依赖创建数据库) ``` sudo npm install -g pm2 sudo apt update && sudo apt install nginx -y sudo docker exec -it mariadb-docker-saver mariadb -u root -p ``` bash 然后输入 `docker-compose.yml` 中你设置的第 111 个(MariaDB)的密码(输入时不会有 `*` 等字符出现,属于正常现象)。进入控制台后粘贴以下脚本: ``` CREATE DATABASE luogu_saver CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; EXIT; ``` bash ### 配置后端[#](#配置后端) 编辑 `config.yml`: ``` cd ~/luogu-saver/packages/backend nano config.yml ``` bash 粘贴以下内容,注意修改自己的密码: ``` port: 3000 env: "development" network: timeout: 30000 db: host: "127.0.0.1" port: 3306 user: "root" password: "你的MariaDB密码" database: "luogu_saver" redis: host: "127.0.0.1" port: 6379 password: "" keyPrefix: "" chroma: enable: false ssl: false host: "127.0.0.1" port: 8000 collectionName: "lgs_articles" queue: save: concurrencyLimit: 2 maxRequestToken: 20 regenerationInterval: 1000 maxQueueLength: 1000 ai: concurrencyLimit: 10 maxRequestToken: 50 regenerationInterval: 1000 maxQueueLength: 2000 update: concurrencyLimit: 2 maxRequestToken: 20 regenerationInterval: 1000 maxQueueLength: 1000 llm: providers: [] scenarios: chat: use: "openai" temperature: 0.7 maxTokens: 2048 topP: 1 frequencyPenalty: 0 presencePenalty: 0 stopSequences: [] summary: use: "openai" temperature: 0.7 maxTokens: 1024 embedding: use: "openai" censor: use: "openai" recommendation: anonymous: expireTime: 604800 maxCount: 100 maxHistory: 500 decayFactor: 0.9 relevantThreshold: 0.75 verification: luogu: codeExpireTime: 300 codeLength: 32 judgement: enabled: true intervalMs: 1200000 runOnStartup: true sourceUrl: "https://www.luogu.com.cn/judgement" ``` yaml 启动后端: ``` pm2 start dist/index.js --name luogu-backend ``` bash ### 托管前端[#](#托管前端) #### 配置 Nginx[#](#配置-nginx) 这是最后一步,让前端页面可以通过 HTTP 访问。 ``` sudo nano /etc/nginx/sites-available/default ``` bash 将内容替换为(注意添加你的生产域名在 `server_name`): ``` server { listen 81; server_name _; # 示例:server_name _ example.com; root /home/ubuntu/luogu-saver/packages/frontend/dist; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { rewrite ^/api/(.*) /$1 break; proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } ``` nginx 保存后,测试并启动 Nginx: ``` ssudo chmod o+x /home/ubuntu sudo chmod -R o+rX /home/ubuntu/luogu-saver/packages/frontend/dist sudo nginx -t sudo systemctl restart nginx sudo systemctl enable nginx ``` bash ### 自定义域名[#](#自定义域名) 在你的域名服务商后台,添加一条 A 记录: - 主机记录:`luogu`(取决于你想用哪个子域名) - 记录值:`你的服务器 IP` - TTL:随意 ### 转发端口[#](#转发端口) 现在,我们需要在 Zeabur 上部署一个 Nginx 服务,专门用来转发流量,是可以通过 808080 端口(`https://example.com`)访问(即访问网站时的默认端口,否则只能通过 `https://example.com:81` 访问,不够优雅)。 在仪表盘右上角点“创建项目”新建一个 Zeabur 项目,点击左侧“新建服务”,点击“模板”,输入“Nginx”部署,然后点“设置”,选择“打开配置文件编辑器”,粘贴以下代码: ``` worker_processes 5; error_log stderr; worker_rlimit_nofile 8192; events {} http { default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] $status ' '"$request" $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /dev/stdout main; sendfile on; tcp_nopush on; server_names_hash_bucket_size 128; server { listen 80 default_server; server_name _; location / { proxy_pass http://服务器 IP:81; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } } ``` nginx 然后点击网络-绑定外部域名,添加你的域名 `example.com` 并确认。 然后会自动开始部署,耐心等待一会,当状态变为运行中时,可以打开你的域名,如果没有问题的话。 恭喜你,部署成功了! ## 参考资料[#](#参考资料) --- ## 拯救谷歌和 Github!你的新“自行车” URL: https://blog.rusin7.com/en/article/devsidecar 快速安装,找到最新版本,安装包选择方式:Windows:De May 14, 2026 1 分钟 [git](/tags/git) # 拯救谷歌和 Github!你的新“自行车” > 快速安装,找到最新版本,安装包选择方式:Windows:De views [| comments](#waline) 还在为谷歌无法访问而发愁吗?[这个宝藏项目 ↗](https://github.com/docmirror/dev-sidecar)一定要收藏好😍!顺便还能秒开 Github! ## 快速安装[#](#快速安装) [打开 Release ↗](https://github.com/docmirror/dev-sidecar/releases),找到最新版本,安装包选择方式: - **Windows**:DevSidecar-x.x.x-windows-universal.exe - **Mac**: DevSidecar-x.x.x-macos-universal.dmg - **Linux**: - Debian 系等支持 Deb 的:DevSidecar-x.x.x-linux-<架构>.deb - 其他:DevSidecar-x.x.x-linux-<架构>.AppImage 安装可能有点慢,建议以下 4 选 1 加速安装(我的是 2.0.2 Windows 版本,具体链接为 [https://gh-proxy.org/+Github ↗](https://gh-proxy.org/+Github) 原始链接): - [主站,全球加速! ↗](https://gh-proxy.org/https://github.com/docmirror/dev-sidecar/releases/download/v2.0.2/DevSidecar-2.0.2-windows-universal.exe) - [香港国内线路优化 ↗](https://hk.gh-proxy.org/https://github.com/docmirror/dev-sidecar/releases/download/v2.0.2/DevSidecar-2.0.2-windows-universal.exe) - [Fastly CDN ↗](https://cdn.gh-proxy.org/https://github.com/docmirror/dev-sidecar/releases/download/v2.0.2/DevSidecar-2.0.2-windows-universal.exe) - [Edgeone 全球加速 ↗](https://edgeone.gh-proxy.org/https://github.com/docmirror/dev-sidecar/releases/download/v2.0.2/DevSidecar-2.0.2-windows-universal.exe) --- ## 图论之欧拉回路、差分约束——算法笔记 URL: https://blog.rusin7.com/en/article/euro-circuit-notes 本文讲述了图论之欧拉回路、差分约束的 C++ 代码,并推荐了比赛和题目以便练习。 ![图论之欧拉回路、差分约束——算法笔记](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Apr 3, 2026 2 分钟 [c++](/tags/c++) # 图论之欧拉回路、差分约束——算法笔记 > 本文讲述了图论之欧拉回路、差分约束的 C++ 代码,并推荐了比赛和题目以便练习。 views [| comments](#waline) # 图论之欧拉回路、差分约束——算法笔记[#](#图论之欧拉回路差分约束算法笔记) [比赛 ↗](https://vjudge.net/contest/767358) ## 欧拉回路[#](#欧拉回路) 无向代码1: ``` void dfs(int x){ while(f[x] using namespace std; int n,m,d[100005],c[100005],f[100005]/*表示遍历到第几个点*/; vectora[100005]; stackst; void dfs(int x){ int l=0; while(f[x]>n>>m; int ind[100005],outd[100005],u,v; for(int i=1;i<=m;++i){ cin>>u>>v; a[u].push_back(v); ind[v]++,outd[u]++; } for(int i=1;i<=n;++i)sort(a[i].begin(),a[i].end()); int x=1,y=0,z=0; for(int i=1;i<=n;++i){ if(ind[i]+1==outd[i])x=i,++y; if(ind[i]!=outd[i])++z; } if(!((y==1&&z==2)||!z)){ cout<<"No"<ans[k.first]+k.second){ ans[i]=min(ans[i],ans[k.first]+k.second),f=1; } } } return f; }; for(int i=0;i using namespace std; int ans[5005]; vector>to[5005]; void Bellman_Ford(int n){ auto relax=[&](){ bool f=0; for(int i=1;i<=n;++i){ for(auto k:to[i]){ if(ans[i]>ans[k.first]+k.second){ ans[i]=min(ans[i],ans[k.first]+k.second),f=1; } } } return f; }; for(int i=0;i>n>>m; fill(ans,ans+n+1,0); for(int i=1;i<=m;++i){ cin>>c1>>c2>>y; to[c1].push_back({c2,y}); } Bellman_Ford(n); return 0; } ``` cpp --- ## 博客迁移分流说明 URL: https://blog.rusin7.com/en/article/explanation-of-blog-migration 博客迁移分流说明在我的陪伴大家4个月后,由于当时技术较差,不会使用 git 命令行和 node.js,所以不够美观 Aug 3, 2026 1 分钟 [公告](/tags/公告) # 博客迁移分流说明 > 博客迁移分流说明在我的陪伴大家4个月后,由于当时技术较差,不会使用 git 命令行和 node.js,所以不够美观 views [| comments](#waline) 在我的[第 222 个博客 ↗](https://old.blog.rusin7.com)陪伴大家 444 个月后,由于主题过于臃肿,加载太慢,迁移所有文章至此,原博客将归档,望周知。 谢谢你们的支持! --- ## 免费获取二级域名并部署 github 仓库 URL: https://blog.rusin7.com/en/article/free-domain 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 Mar 23, 2026 5 分钟 [白嫖](/tags/白嫖) / [建站](/tags/建站) / [github](/tags/github) / [cloudflare](/tags/cloudflare) / [教程](/tags/教程) # 免费获取二级域名并部署 github 仓库 > 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 views [| comments](#waline) ## 前提[#](#前提) 拥有一个 [Github ↗](https://github.com) 的账号和博客仓库。 ## 领取域名[#](#领取域名) ### 注册[#](#注册) #### Github[#](#github) 前往 {% btn ‘[https://github.com/signup’,Github,anzhiyufont ↗](https://github.com/signup',Github,anzhiyufont) anzhiyu-icon-circle-arrow-right,purple larger %} 注册账号。 #### DigitalPlat Domains[#](#digitalplat-domains) 前往 {% btn ‘[https://dash.domain.digitalplat.org/signup?ref=uGQR48cE9B’,Digitalplat,anzhiyufont ↗](https://dash.domain.digitalplat.org/signup?ref=uGQR48cE9B',Digitalplat,anzhiyufont) anzhiyu-icon-circle-arrow-right,purple larger %} 注册账号,完整人名、电话号码、完整地址等信息不用填写真实的,可以在 [美国身份生成器 ↗](https://www.meiguodizhi.com/) 生成。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/2.png) 注册完成后会发一封验证到邮箱。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/3.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/4.png) 登录后需要 KYC 验证(使用 Github 账号即可)。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/5.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/6.png) 验证成功后会显示这个页面。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/7.png) ### 获取[#](#获取) 书接上回,点击左侧 注册。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/8.png) {% tip error %}Digitalplat 于 2026/3/20(文章发布约一周后) 左右更新 UI 和页面交互,文章中获取部分截图为旧版,可能无法对应位置,但操作基本相同。{% endtip %} {% tip fa-atom, sync %}UppubDatetime: 本文章已更新至最新。{% endtip %} {% link 旧版存档,点击查看旧版,[https://life.rusin7.com/post/dpdns-org/ ↗](https://life.rusin7.com/post/dpdns-org/) %} {% link DigitalPlat Domains 仪表盘,下滑找到我的域名统计-最大允许域名数,[https://dash.domain.digitalplat.org/dashboard ↗](https://dash.domain.digitalplat.org/dashboard) %} 下滑找到我的域名统计-最大允许域名数,正常是 222 个,如果你开始没按我的教程注册是 111 个。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/9.png) {% note info flat %} 每个账户理论上可以注册 333 个免费的 dpdns.org 域名。 - 第 222 个需要在注册时, Referral code 填 `uGQR48cE9b` 或 `QFFXW3uiRm`,如果按前面我的教程一步步注册,可以默认拥有 222 个,再 star 一下获得第 333 个。 - 第 333 个需要给他们的 Github 项目 star,点击验证通过后就可以,验证不难。 {% endnote %} - 登录 Github。 - {% btn ‘[https://github.com/DigitalPlatDev/FreeDomain’,访问仓库,anzhiyufont ↗](https://github.com/DigitalPlatDev/FreeDomain',%E8%AE%BF%E9%97%AE%E4%BB%93%E5%BA%93,anzhiyufont) anzhiyu-icon-circle-arrow-right %}。 - 点击右上角 ⭐“Star”。 - 点击 {% btn ‘[https://dash.domain.digitalplat.org/auth/kyc/github’,这里,anzhiyufont ↗](https://dash.domain.digitalplat.org/auth/kyc/github',%E8%BF%99%E9%87%8C,anzhiyufont) anzhiyu-icon-circle-arrow-right %}。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/10.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/11.png) [https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/sourcehttps://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/12.png ↗](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/sourcehttps://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/12.png) * * * 点击 {% btn 'https://dash.domain.digitalplat.org/panel/main?page=%2Fpanel%2Fregister',注册,anzhiyufont anzhiyu-icon-circle-arrow-right,pink larger %},填写想注册的域名。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/12.png) 如果被占用,可以换个域名试试,被占用图片: ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/13.png) 红框中的 \*Name Server1,\*Name Server2先填 `1.com` 和 `2.com`,等会儿可以修改。未被占用图片: ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/14.png) 域名注册成功后会显示这个页面。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/15.png) ## 托管到 CF[#](#托管到-cf) ### 登录[#](#登录) 用 Github [登录 Cloudflare ↗](https://dash.cloudflare.com/login)。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772802324633.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772802412422.png) ### 添加[#](#添加) 点击添加站点(Onboard a domain)。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772802648682.png) 选择免费版继续。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772804243558.png) 类型选择 CHAME,名称填写 `@` ,目标填写 Github page 地址(username.github.io,将 username 替换为你的 Github 用户名),点击保存(Save)。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772804929713.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772804934072.png) 保存后效果如下图。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772805054433.png) 点击底部蓝色 继续激活 按钮。 ### 修改 Name Server[#](#修改-name-server) 回到[注册域名的网站 ↗](https://dash.domain.digitalplat.org/domains),点击刚刚的域名,下滑页面,找到原来是 1.com 和 2.com 的 Name server。在 Cloudflare 页面点击 显示名称服务器指令 ( `Show nameserver instructions` ) 依次点击 Click to copy 按钮并依次复制到刚刚的域名的 Name server 1 和 Name server 2,修改后继续在注册域名的网站点击 `更新名称服务器` ( `UppubDatetime nameservers` ),成功后效果如下图。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/16.png) ### 检查[#](#检查) 回到 Cloudflare,点击 `现在就检查名称服务器` ( `Check nameservers now` )。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772848750931.png) 域名注册商可能需要 333 分钟 ∼24\\sim 24∼24 小时来处理 Nameserver 的更新,当你的网站在 Cloudflare 上激活后,你会收到一封邮件通知。 你也可以保留 Cloudflare 页面,当显示如下两图时,说明检查成功了。 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772851053998.png) 单个域名概述页面 ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772851718121.png) ![截屏](https://jsd.liiiu.cn/gh/ruying-suixing/blog/themes/hexo-theme-anzhiyu-1.7.1/source/img/2026/46209/1772851759034.png) 所有域名管理页面 ## 结语[#](#结语) 可以愉快地享用Cloudflare的服务了! 祝大家打造出品牌化的个人博客,为平凡的生活添彩! --- ## Cyanwind theme markdown syntax URL: https://blog.rusin7.com/en/article/how-to-use-markdown Learn the basic syntax of Markdown from beginner to advanced. Aug 28, 2026 / Update Aug 31, 2026 10 分钟 en [tutorial](/tags/tutorial) / [markdown](/tags/markdown) # Cyanwind theme markdown syntax > Learn the basic syntax of Markdown from beginner to advanced. views [| comments](#waline) ## What is Markdown[#](#what-is-markdown) [Markdown ↗](https://markdown.com.cn/ "Official website") is a lightweight markup language with a simple syntax that allows people to focus more on the content itself rather than formatting. It uses a plain text format that is easy to read and write, and can be mixed with HTML. It can export to HTML, PDF, and its own .md format. Due to its simplicity, efficiency, readability, and ease of writing, Markdown is widely used by platforms like Github, Wikipedia, and Jianshu. ## Markdown Editors[#](#markdown-editors) The best way to get started with Markdown is to use it frequently. Thanks to the many free tools available, getting started with Markdown is very convenient. Unfortunately, **different platforms may use Markdown parsing engines implemented in different languages**, for example Gridea and Luogu are different, and they may have different levels of customization and extensions. This means the experience of writing with Markdown on different platforms is not completely consistent. However, thankfully, all platforms support the commonly accepted standard syntax. You don’t even need to download any programs—you can use an [online Markdown editor ↗](https://markdown.com.cn/editor/) to write Markdown. Simply visit the website and start writing in the left pane. The rendered document is previewed in the right pane. While reading this guide, you can open the [online Markdown editor ↗](https://markdown.com.cn/editor). This way, you can practice Markdown syntax while learning it. Once you’re familiar with Markdown, you can choose a Markdown application that suits you. ## Markdown Heading Syntax[#](#markdown-heading-syntax) Markdown headings are created by inserting 1 to 6 `#` symbols at the beginning of a line, with one or more spaces between the `#` and the heading text, corresponding to heading levels 1 through 6. Warning Headings are **not meant** for emphasis. Overusing headings may confuse readers. ### Preview[#](#preview) ![Preview](https://image.rusin7.com/file/hexo/article/markdown/851kcAXJ.png) ### Source[#](#source) ``` # Heading level 1 ## Heading level 2 ### Heading level 3 #### Heading level 4 ##### Heading level 5 ###### Heading level 6 This is body text. ``` markdown ### Alternative Syntax[#](#alternative-syntax) You can also add any number of `==` symbols below the text to mark a level 1 heading, or `--` symbols for a level 2 heading. > **Warning** If you want to add a horizontal rule after a line of text, use `***` instead of `---` to avoid mistakenly marking it as a level 2 heading. #### Preview[#](#preview-1) ![Preview](https://image.rusin7.com/file/hexo/article/markdown/OtaGC9sA.png) #### Source[#](#source-1) ``` Heading level 1 =============== Heading level 2 --------------- ``` markdown ## Markdown Emphasis Syntax[#](#markdown-emphasis-syntax) You can emphasize the importance of text by making it bold, italic, strikethrough, or highlighted. ### Preview[#](#preview-2) _Single asterisk italic_ _Single underscore italic_ **Double asterisk bold** **Double underscore bold** Strikethrough _**Mixed effect**_ ### Source[#](#source-2) ``` *Single asterisk italic* _Single underscore italic_ **Double asterisk bold** __Double underscore bold__ ~~Strikethrough~~ ***Mixed effect*** ``` markdown If you want to insert a plain asterisk or underscore before or after text, you can use a backslash (`\`) (see the [“Escape Characters” section](#markdown-escape-syntax) below). ### Preview[#](#preview-3) Using a backslash at the beginning treats it as a plain character. ### Source[#](#source-3) ``` \*Using a backslash at the beginning\* treats it as a plain character\* ``` markdown ## Markdown Code Syntax[#](#markdown-code-syntax) ### Code Blocks[#](#code-blocks) To create a code block in Markdown, place `at the beginning and end of the code block, each on its own line. You can add a language name after the opening` on the first line, such as c++, java, c, pascal, markdown, latex, etc. #### Preview[#](#preview-4) ``` #include using namespace std; int main(){ int a, b; cin >> a >> b; cout << a + b << endl; return 0; } ``` c #### Source[#](#source-4) ```` ```c++ #include using namespace std; int main(){ int a, b; cin >> a >> b; cout << a + b << endl; return 0; } ```` markdown ```` ### Inline Code When you need to reference code, if the reference is only a single line and not broken into multiple lines, you can wrap it in backticks. #### Preview This way you can `reference code inline`. #### Source ```markdown This way you can `reference code inline`. ```` plaintext ## Markdown Blockquote Syntax[#](#markdown-blockquote-syntax) ### Preview[#](#preview-5) > Markdown marks blockquotes by adding `>` at the beginning of the line. > > You can also add `>` only at the beginning of the first line of the entire paragraph. > > > Blockquotes can be nested by adding different numbers of `>` according to the nesting level. > > > > _I am a nested blockquote, and I can use other Markdown syntax._ > > > > ### You can use heading syntax inside blockquotes.[#](#you-can-use-heading-syntax-inside-blockquotes) > > > > - Yes, you can add lists. > > - No, you can add lists. > > > > ``` > > //You can add code blocks inside blockquotes > > import java.net.URL; > > import java.util.Arrays; > > import java.util.Date; > > import java.util.Set; > > ``` > > > > java ### Source[#](#source-5) ``` > Markdown marks blockquotes by adding `>` at the beginning of the line. > > You can also add `>` only at the beginning of the first line of the entire paragraph. > > Blockquotes can be nested by adding different numbers of `>` according to the nesting level. > > > > *I am a nested blockquote, and I can use other Markdown syntax.* > > > > ### You can use heading syntax inside blockquotes. > > - [x] Yes, you can add lists. > > - [ ] No, you can add lists. > > ```java > > //You can add code blocks inside blockquotes > > import java.net.URL; > > import java.util.Arrays; > > import java.util.Date; > > import java.util.Set; > > ``` ``` markdown ## Markdown List Syntax[#](#markdown-list-syntax) Markdown supports ordered lists, unordered lists, and task lists. Unordered lists use asterisks, plus signs, or hyphens as list markers. Ordered lists use numbers followed by a period. The format for both list types is: list marker + space + list item. List item markers are usually placed at the far left, but can be indented up to 3 spaces. After the list marker, there must be at least one space or tab. Lists **can** be nested. ### Unordered Lists[#](#unordered-lists) The three types of list markers (asterisk, plus sign, and hyphen) produce the same result. #### Preview[#](#preview-6) - Red - Green - Blue - Red - Green - Blue - Red - Green - Blue #### Source[#](#source-6) ``` * Red * Green * Blue + Red + Green + Blue - Red - Green - Blue ``` markdown ### Ordered Lists[#](#ordered-lists) Ordered lists use numbers followed by a period `.` or parentheses `(`, adding items with numbers and periods. Numbers **do not** have to be in numerical order, but the list should start with the number 1. #### Preview[#](#preview-7) 1. First item 2. Second item 3. Third item 4. Fourth item * * * 1. First item 2. Second item 3. Third item 4. Fourth item * * * 1. First item 2. Second item 3. Third item 1. Indented item 2. Indented item 4. Fourth item #### Source[#](#source-7) ``` 1. First item 2. Second item 3. Third item 4. Fourth item --- 1. First item 1. Second item 1. Third item 1. Fourth item --- 1) First item 3) Second item 8) Third item 1) Indented item 2) Indented item 5) Fourth item ``` markdown ### Task Lists[#](#task-lists) Task lists are a special type of list that allow you to add checkboxes before list items to indicate whether a task is complete. The format for task lists is: `- [ ] Task item` or `- [x] Task item`, where `[ ]` indicates an incomplete task and `[x]` indicates a completed task. #### Preview[#](#preview-8) - Learn Markdown syntax - Complete Markdown syntax learning - Write Markdown documentation #### Source[#](#source-8) ``` - [ ] Learn Markdown syntax - [x] Complete Markdown syntax learning - [ ] Write Markdown documentation ``` plaintext ## Markdown Link Syntax[#](#markdown-link-syntax) Links provide readers with better website navigation and rendering. ### Inline Links[#](#inline-links) Link text is placed inside square brackets, and the link URL is placed inside parentheses immediately after. The link title is optional text that appears when hovering over the link, placed after the URL inside parentheses and separated by a space. #### Preview[#](#preview-9) [Inline link title (no title) ↗](https://ruying-suixing.github.io/) [Inline link title (with title), hover over the link to see the title effect. ↗](https://ruying-suixing.github.io/ "Optional title") \*\*[Inline\*\* _link_ title (with Markdown syntax) ↗](https://ruying-suixing.github.io/) #### Source[#](#source-9) ``` [Inline link title (no title)](https://ruying-suixing.github.io/) [Inline link title (with title), hover over the link to see the title effect.](https://ruying-suixing.github.io/ "Optional title") [**Inline** _link_ title (with Markdown syntax)](https://ruying-suixing.github.io/ "Optional title") ``` markdown ## Markdown Image Syntax[#](#markdown-image-syntax) Markdown uses syntax similar to links to mark images. When publishing content with images on the internet, you need to upload the image to publicly accessible storage (commonly known as an image host). You can use an image host to upload images and then copy the image reference URL to use the image. The inline image syntax is as follows: `![Alt text](image relative or absolute path)` `![Alt text](image relative or absolute path "Optional title")` The detailed description is: an exclamation mark `!`, followed by square brackets containing alternative text for the image (these words will be displayed if the image fails to load), then parentheses containing the image URL. Finally, you can optionally add title text in quotes, similar to link syntax. ### Preview[#](#preview-10) No title: ![My blog image](https://cdn.luogu.com.cn/upload/usericon/1620655.png) With title, hover over the image to see the title effect: ![My blog image](https://cdn.luogu.com.cn/upload/usericon/1620655.png "Optional title") Invalid link, with title, hover over the error text to see the title effect: ![My blog image](https://cdn.luogu.com.cn/upload/usericon/9999999.png "Optional title") Image in link: ![My blog image](https://cdn.luogu.com.cn/upload/usericon/1620655.png "Optional title") [↗](https://ruying-suixing.github.io/) ### Source[#](#source-10) ``` No title: ![My blog image](https://cdn.luogu.com.cn/upload/usericon/1620655.png) With title, hover over the image to see the title effect: ![My blog image](https://cdn.luogu.com.cn/upload/usericon/1620655.png "Optional title") Invalid link, with title, hover over the error text to see the title effect: ![My blog image](https://cdn.luogu.com.cn/upload/usericon/9999999.png "Optional title") Image in link: ![My blog image](https://cdn.luogu.com.cn/upload/usericon/1620655.png "Optional title")[](https://ruying-suixing.github.io/) ``` markdown ## Markdown Escape Syntax[#](#markdown-escape-syntax) To display characters that are normally used to format Markdown documents, add a backslash character before them. Rendering effect: Without the backslash, this would be a bullet in an unordered list. ### Escapable Characters[#](#escapable-characters) All of the following characters can be escaped by using a backslash character. | Character | Name | | --- | --- | | \ | backslash | | ` | backtick | | * | asterisk | | _ | underscore | | { } | curly braces | | [ ] | brackets | | ( ) | parentheses | | # | pound sign | | + | plus sign | | - | minus sign (hyphen) | | . | dot | | ! | exclamation mark | ### Preview[#](#preview-11) \\ Backslash \` Backtick - Asterisk \_ Underscore {} Curly braces \[\] Brackets () Parentheses # Pound sign + Plus sign - Minus sign . Dot ! Exclamation mark ### Source[#](#source-11) ``` \\ Backslash \` Backtick \* Asterisk \_ Underscore \{} Curly braces \[] Brackets \() Parentheses \# Pound sign \+ Plus sign \- Minus sign \. Dot \! Exclamation mark ``` markdown ## Markdown Horizontal Rule Syntax[#](#markdown-horizontal-rule-syntax) To create a horizontal rule, use three or more asterisks (`***`), hyphens (`---`), or underscores (`___`) on a line by themselves, with no other content. ### Preview[#](#preview-12) This is the first paragraph. * * * * * * * * * This is the second paragraph. ### Source[#](#source-12) ``` This is the first paragraph. *** --- _________________ This is the second paragraph. ``` markdown ## Markdown Table Syntax[#](#markdown-table-syntax) Use `|` to separate cells, and use `:` with three or more `-` in the second row to adjust alignment. ### Preview[#](#preview-13) | Left aligned | Center aligned | Right aligned | | --- | --- | --- | | Content | Content | Content | ### Source[#](#source-13) ``` | Left aligned | Center aligned | Right aligned | |:---|:---:|---:| | Content | Content | Content | ``` markdown The width of cells in the source can vary, as shown below. The rendered output will look the same. ### Preview[#](#preview-14) | Left aligned | Center aligned | Right aligned | | --- | --- | --- | | Content | Content | Content | ### Source[#](#source-14) ``` | Left aligned | Center aligned | Right aligned | | :--- | :---: | ---: | | Content | Content | Content | ``` markdown The number of table rows can vary, as shown below. ### Preview[#](#preview-15) | Left aligned | Center aligned | Right aligned | | --- | --- | --- | | Content | Content | Content | | Content | Content | Content | | Content | Content | Content | | Content | Content | Content | | Content | Content | Content | ### Source[#](#source-15) ``` | Left aligned | Center aligned | Right aligned | |:---|:---:|---:| | Content | Content | Content | | Content | Content | Content | | Content | Content | Content | | Content | Content | Content | | Content | Content | Content | ``` markdown ## Markdown Comment Syntax[#](#markdown-comment-syntax) Markdown does not have built-in comment functionality, but you can use an unofficial hack method. ### Preview[#](#preview-16) This is a visible paragraph. This is another visible paragraph. ### Source[#](#source-16) ``` This is a visible paragraph. [This is a hidden comment]: # This is another visible paragraph. ``` markdown ## Cyanwind Theme Extended Syntax[#](#cyanwind-theme-extended-syntax) The Cyanwind theme integrates many extended syntaxes from [Luogu ↗](https://www.luogu.com.cn/article/70w8j2pj) for writing articles. Of course, you can also achieve this in Hexo by modifying the source code. The tutorial can be found at [Replicating Luogu Plugins in Hexo](/article/luogu-plugin-in-hexo). Markdown does not have text alignment syntax, but you can use the extended syntax included in this theme to solve this. ### Preview[#](#preview-17) Left-aligned content. Center-aligned content. Right-aligned content. ### Source[#](#source-17) ``` :::align{left} Left-aligned content. ::: :::align{center} Center-aligned content. ::: :::align{right} Right-aligned content. ::: ``` markdown Markdown does not have collapsible box syntax, but you can also use the extended syntax included in this theme to solve this. ### Preview[#](#preview-18) This is a tip I am tip content. I am a parent container I am some text. I am child container 1 I am content 1. I am some text. I am child container 2 I am child container 3 I am content 2. I am some text. ### Source[#](#source-18) ``` :::info[This is a tip] I am tip content. ::: :::::warning[I am a parent container] I am some text. ::::success[I am child container 1]{open} I am content 1. :::: I am some text. ::::success[I am child container 2]{open} :::error[I am child container 3]{open} I am content 2. ::: :::: I am some text. ::::: ``` markdown Markdown does not have Codeforces-style blockquote syntax, but you can also use the extended syntax included in this theme to solve this. ### Preview[#](#preview-19) Hello everyone, I am talking about reason. ——otto ### Source[#](#source-19) ``` :::epigraph[——otto] Hello everyone, I am talking about reason. ::: ``` plaintext Although nesting is supported, **please do not overuse it**. --- ## JC 提高班期末测试题解 URL: https://blog.rusin7.com/en/article/jc-the-end-of-class-test-solution 题目描述雪花图是由两个整数x和y均大于1生成的,生成方式如下 Jun 6, 2026 9 分钟 [题解](/tags/题解) / [比赛](/tags/比赛) # JC 提高班期末测试题解 > 题目描述雪花图是由两个整数x和y均大于1生成的,生成方式如下 views [| comments](#waline) # [T1 雪花图 ↗](https://www.luogu.com.cn/problem/CF1829F)[#](#t1-雪花图) ## 题目描述[#](#题目描述) 雪花图是由两个整数 xxx 和 yyy(均大于 111)生成的,生成方式如下: - 以一个中心顶点开始。 - 将 xxx 个新顶点与该中心顶点相连。 - 对每一个这 xxx 个顶点,各自连接 yyy 个新顶点。 例如,下图是 x\=5x=5x\=5,y\=3y=3y\=3 的雪花图。 ![1](https://cdn.luogu.com.cn/upload/vjudge_pic/CF1829F/8093abf53ab9afd4293f2937f4849e3ca604a47a.png) 上图中的雪花图有一个中心顶点 151515,然后有 x\=5x=5x\=5 个顶点与其相连(333、666、777、888 和 202020),每个顶点又分别连接 y\=3y=3y\=3 个顶点。 给定一个雪花图,请你求出 xxx 和 yyy 的值。 ## 输入格式[#](#输入格式) 第一行包含一个整数 ttt(1≤t≤10001 \\leq t \\leq 10001≤t≤1000),表示测试用例的数量。 每个测试用例的第一行包含两个整数 nnn 和 mmm(2≤n≤2002 \\leq n \\leq 2002≤n≤200;1≤m≤min⁡(1000,n(n−1)2)1 \\leq m \\leq \\min\\left(1000, \\frac{n(n-1)}{2}\\right)1≤m≤min(1000,2n(n−1)​)),分别表示图中的顶点数和边数。 接下来的 mmm 行,每行包含两个整数 uuu 和 vvv(1≤u,v≤n1 \\leq u, v \\leq n1≤u,v≤n,u≠vu \\neq vu\=v),表示一条连接顶点 uuu 和 vvv 的边。图中没有重边和自环。 保证给定的图一定是某组大于 111 的整数 xxx 和 yyy 所对应的雪花图。 ## 输出格式[#](#输出格式) 对于每个测试用例,输出一行,包含两个整数 xxx 和 yyy,用空格分隔,顺序不能颠倒。 ## 输入输出样例 #1[#](#输入输出样例-1) ### 输入 #1[#](#输入-1) ``` 3 21 20 21 20 5 20 13 20 1 3 11 3 10 3 4 8 19 8 14 8 9 7 12 7 17 7 18 6 16 6 2 6 6 15 7 15 8 15 20 15 3 15 7 6 1 2 1 3 2 4 2 5 3 6 3 7 9 8 9 3 3 6 6 2 2 1 5 2 2 7 4 3 3 8 ``` plaintext ### 输出 #1[#](#输出-1) ``` 5 3 2 2 2 3 ``` plaintext ## 说明/提示[#](#说明提示) 第一个测试用例如题面所示。注意输出 3 53\\ 53 5 是错误的,因为 xxx 应该在 yyy 之前输出。 ``` #include using namespace std; int t,n,m,cnt[205],mx,ends1[205],u[1005],v[1005]; int check(int x){ for(int i=1;i<=m;++i){ if((u[i]==x&&ends1[v[i]]==1)||(v[i]==x&&ends1[u[i]]==1)){ return 0; } } return 1; } int main(){ cin>>t; while(t--){ int x=0,y=0; cin>>n>>m; memset(ends1,0,sizeof ends1),memset(cnt,0,sizeof cnt),mx=0; for(int i=1;i<=m;++i){ cin>>u[i]>>v[i]; cnt[u[i]]++,cnt[v[i]]++; mx=max({u[i],v[i],mx}); } for(int i=1;i<=mx;++i){ if(cnt[i]==1){ ends1[i]=1; y++; } } for(int j=1;j<=n;++j){ if(ends1[j]!=1&&check(j)){ x=cnt[j]; }else if(ends1[j]!=1&&check(j)){ x=cnt[j]; } } cout< 前景介绍使用方法创建JS文件 views [| comments](#waline) ## 前景介绍[#](#前景介绍) 背景 基于{% btn ‘[https://blog.bsgun.cn/posts/ef58a648/‘,梦爱吃鱼的教程 ↗](https://blog.bsgun.cn/posts/ef58a648/',%E6%A2%A6%E7%88%B1%E5%90%83%E9%B1%BC%E7%9A%84%E6%95%99%E7%A8%8B) %}进行修改,主要改进是**更换 API 地址**,因为[原 API ↗](https://api.nsmao.net/) 已经失效。 ## 使用方法[#](#使用方法) ### 创建 JS 文件[#](#创建-js-文件) 在博客主题目录的 js 文件夹(~\\themes\\anzhiyu\\source\\js)下创建 welcome.js 文件(也可以在source文件夹下另外新建文件夹)。 ### 配置经纬度[#](#配置经纬度) {% btn ‘[https://uapis.cn/api/v1/network/myip?source=commercial’,点击这里 ↗](https://uapis.cn/api/v1/network/myip?source=commercial',%E7%82%B9%E5%87%BB%E8%BF%99%E9%87%8C) %},找到 ``` "latitude": xxx,"longitude": xxx, ``` plaintext 复制对应的经度(lng)和纬度(lat)值。 * * * 将以下内容复制到 `welcome.js` 中,并修改文件顶部配置信息 代码 ``` window.IP_CONFIG = { BLOG_LOCATION: { lng: 121.4, // 博主经度 lat: 29.9, // 博主纬度 }, CACHE_DURATION: 1000 * 60 * 60, // 缓存1小时 HOME_PAGE_ONLY: true, // 是否只在首页显示 }; // 添加样式 const addStyles = () => { const style = document.createElement('style'); style.textContent = ` #welcome-info { user-select: none; display: flex; justify-content: center; align-items: center; height: 212px; padding: 10px; margin-top: 5px; border-radius: 12px; background-color: var(--anzhiyu-background); outline: 1px solid var(--anzhiyu-card-border); } .loading-spinner { width: 50px; height: 50px; border: 3px solid rgba(0, 0, 0, 0.1); border-radius: 50%; border-top: 3px solid var(--anzhiyu-main); animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .ip-address { filter: blur(5px); transition: filter 0.3s ease; } .ip-address:hover { filter: blur(0); } .error-message { color: #ff6565; display: flex; flex-direction: column; justify-content: center; align-items: center; } .error-message p, .permission-dialog p { margin: 0; } .error-icon { font-size: 3rem; } #retry-button { margin: 0 5px; color: var(--anzhiyu-main); transition: transform 0.3s ease; cursor: pointer; } #retry-button:hover { transform: rotate(180deg); } `; document.head.appendChild(style); }; // 获取欢迎信息元素 const getWelcomeInfoElement = () => document.querySelector('#welcome-info'); // 显示加载动画 const showLoadingSpinner = () => { const welcomeInfoElement = getWelcomeInfoElement(); if (!welcomeInfoElement) return; welcomeInfoElement.innerHTML = '
'; }; // 显示错误信息 const showErrorMessage = (message = '抱歉,无法获取信息') => { const welcomeInfoElement = getWelcomeInfoElement(); if (!welcomeInfoElement) return; welcomeInfoElement.innerHTML = `
😕

${message}

请重试或检查网络连接

`; document.getElementById('retry-button').addEventListener('click', fetchIpInfo); }; // 缓存相关 const IP_CACHE_KEY = 'ip_info_cache'; const getIpInfoFromCache = () => { const cached = localStorage.getItem(IP_CACHE_KEY); if (!cached) return null; const { data, timestamp } = JSON.parse(cached); if (publishDate.now() - timestamp > IP_CONFIG.CACHE_DURATION) { localStorage.removeItem(IP_CACHE_KEY); return null; } return data; }; const setIpInfoCache = (data) => { localStorage.setItem(IP_CACHE_KEY, JSON.stringify({ data, timestamp: publishDate.now() })); }; // 计算距离 const calculateDistance = (lng, lat) => { const R = 6371; // 地球半径(km) const rad = Math.PI / 180; const dLat = (lat - IP_CONFIG.BLOG_LOCATION.lat) * rad; const dLon = (lng - IP_CONFIG.BLOG_LOCATION.lng) * rad; const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(IP_CONFIG.BLOG_LOCATION.lat * rad) * Math.cos(lat * rad) * Math.sin(dLon / 2) * Math.sin(dLon / 2); return Math.round(R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))); }; // 格式化IP显示 const formatIpDisplay = (ip) => { if (!ip) return "未知IP"; return ip.includes(":") ? "IPv6地址" : ip; }; // 格式化位置 const formatLocation = (region) => { if (!region) return '神秘地区'; return region.replace(/\s+/g, " "); }; // 时段问候 const getTimeGreeting = () => { const hour = new publishDate().getHours(); if (hour < 11) return "早上好🌤️,一日之计在于晨"; if (hour < 13) return "中午好☀️,记得午休喔~"; if (hour < 17) return "下午好🕞,饮茶先啦!"; if (hour < 19) return "即将下班🚶‍♂️,记得按时吃饭~"; return "晚上好🌙,夜生活嗨起来!"; }; // ====================== 终极修复:适配 浙江、江苏 这种简写 ====================== const getGreeting = (region) => { if (!region) return "带我去你的城市逛逛吧!"; const parts = region.trim().split(/\s+/).filter(Boolean); const province = parts[1] || ""; const city = parts[2] || ""; if (city === "南京") return "六朝古都,风华依旧"; if (city === "苏州") return "上有天堂,下有苏杭"; if (city === "杭州") return "东风渐绿西湖柳,雁已还人未南归"; if (city === "郑州") return "豫州之域,天地之中"; if (city === "洛阳") return "洛阳城里见秋风,欲作家书意万重"; if (city === "开封") return "包公那叫一个铁面无私,严惩贪官污吏"; if (city === "宁波") return "海上丝路的起点,和我一个城市。"; if (city === "西安") return "十三朝古都,长治久安!"; // 省份匹配(简写版) if (province === "北京") return "北京欢迎你~~~"; if (province === "天津") return "讲段相声吧"; if (province === "河北") return "山势巍巍成壁垒,天下雄关"; if (province === "山西") return "展开坐具长三尺,已占山河五百余"; if (province === "内蒙古") return "天苍苍,野茫茫,风吹草低见牛羊"; if (province === "辽宁") return "我想吃烤鸡架!"; if (province === "吉林") return "状元阁就是东北烧烤之王"; if (province === "黑龙江") return "很喜欢哈尔滨大剧院"; if (province === "上海") return "众所周知,中国只有两个城市"; if (province === "江苏") return "散装是必须要散装的"; if (province === "浙江") return "望海楼明照曙霞,闲塘十里尽梅花"; if (province === "河南") return "可否带我品尝河南烩面啦?"; return "欢迎来到我的博客!"; }; // ============================================================================== // 生成欢迎信息 const generateWelcomeMessage = (region, dist, ipDisplay) => { const location = formatLocation(region); const timeGreet = getTimeGreeting(); const cityGreet = getGreeting(region); return ` 欢迎来自 ${location} 的小友💖
你当前距博主约 ${dist} 公里!
你的IP地址:${ipDisplay}
${timeGreet}
Tip:${cityGreet}🍂 `; }; const showWelcome = (data) => { if (!data || !data.ip) return showErrorMessage(); const welcomeInfo = getWelcomeInfoElement(); if (!welcomeInfo) return; const dist = calculateDistance(data.longitude, data.latitude); const ipDisplay = formatIpDisplay(data.ip); welcomeInfo.style.display = 'block'; welcomeInfo.style.height = 'auto'; welcomeInfo.innerHTML = generateWelcomeMessage(data.region, dist, ipDisplay); }; // 从uapis.cn获取IP信息 const fetchIpData = async () => { const response = await fetch('https://uapis.cn/api/v1/network/myip?source=commercial'); if (!response.ok) throw new Error('API请求失败'); const result = await response.json(); return result; }; // 获取IP信息主函数 const fetchIpInfo = async () => { showLoadingSpinner(); const cachedData = getIpInfoFromCache(); if (cachedData) { showWelcome(cachedData); return; } try { const data = await fetchIpData(); setIpInfoCache(data); showWelcome(data); } catch (error) { console.error('获取IP信息失败:', error); showErrorMessage('获取IP信息失败,请重试'); } }; const isHomePage = () => { return window.location.pathname === '/' || window.location.pathname === '/index.html'; }; // 插入组件 const insertAnnouncementComponent = () => { const announcementCards = document.querySelectorAll('.card-widget.card-announcement'); if (!announcementCards.length) return; if (IP_CONFIG.HOME_PAGE_ONLY && !isHomePage()) { announcementCards.forEach(card => card.remove()); return; } if (!document.querySelector('#welcome-info')) return; fetchIpInfo(); }; document.addEventListener('DOMContentLoaded', () => { addStyles(); insertAnnouncementComponent(); document.addEventListener('pjax:complete', insertAnnouncementComponent); }); ``` javascript ## 插入 JS 文件[#](#插入-js-文件) 在 `_config.anzhiyu.yml` (或其他主题)主题配置文件下 `inject` 配置项中的 `bottom` 引入 `welcome.js`。 ``` - ``` yaml {% tip info %}图片内容仅供参考,具体根据实际情况修改。{% endtip %} ![截屏](/img/2026/2780309151/1.png) ## 配置内容[#](#配置内容) 确认 `_config.anzhiyu.yml` (或其他主题)主题配置文件下 `aside` 配置项中的 `card_announcement` 是否开启,配置参考: ``` card_announcement: enable: true # 必须开启 content: ···(省略)
# 必须项 ``` yaml ![截屏](/img/2026/2780309151/2.png) * * * {% folding yellow, 注意事项 %} - 确保API密钥正确填写,正确设置白名单 - 经纬度没必要填写详细,为了自身隐私安全 - 选择器可以根据你的主题实际情况修改 {% endfolding %} ## 常见问题[#](#常见问题) **Q**: 为什么显示”无法获取信息”? **A**: 可能是 API 炸了,检查配置并重试。实在不行联系我更新文章。 **Q**: 距离显示不准确? **A**: 正常现象,计算有无法避免的误差,大概就行了。 --- ## 洛谷网校 CSP 初赛笔记 URL: https://blog.rusin7.com/en/article/luogu-class-csp-j-note 笔记 Jul 22, 2026 2 分钟 [c++](/tags/c++) # 洛谷网校 CSP 初赛笔记 > 笔记 views [| comments](#waline) ## 位运算[#](#位运算) - `&` 如果 x,yx,yx,y 的对应位都为 111,则结果为 111,否则结果为 000。 - `|` 如果 x,yx,yx,y 的对应位都为 000,则结果为 000,否则结果为 111。 - `^` 如果 x,yx,yx,y 的对应位不同,则结果为 111,否则结果为 000。 - `<<` xxx 左移 yyy 位,高位删除,如:(1010)2<<2\=1000(1010)\_{2}\\texttt{<<}2=1000(1010)2​<<2\=1000; - `>>` xxx 右移 yyy 位,低位删除,如:(1010)2\>>2\=0010(1010)\_{2}\\texttt{>>}2=0010(1010)2​\>>2\=0010; ### 应用[#](#应用) ``` n^=1<>x)&1;//获得n的第x位 ``` cpp ### 优先级表[#](#优先级表) `~`\>`<<`和`>>`\>`&`\>`^`\>`|`,同级运算从左向右。 如图,是所有运算的优先级表: ![优先级表](https://image.rusin7.com/file/81VTdvyM.png) ## ASCLL 码[#](#ascll-码) - 0∼90 \\sim 90∼9 : 48∼5748 \\sim 5748∼57 - `A` ∼\\sim∼ `Z`: 65∼9065 \\sim 9065∼90 - `a` ∼\\sim∼ `a`: 97∼12297 \\sim 12297∼122 详情 以数字 0∼90 \\sim 90∼9 开头的都是数字,例如:0x3f3f3f\\texttt{0x3f3f3f}0x3f3f3f --- ## 在 Hexo 中复现洛谷插件 URL: https://blog.rusin7.com/en/article/luogu-plugin-in-hexo 前言OIer都知道,洛谷中有个,非常好用,效果如下:succ Jun 7, 2026 13 分钟 [hexo](/tags/hexo) / [安知鱼美化](/tags/安知鱼美化) # 在 Hexo 中复现洛谷插件 > 前言OIer都知道,洛谷中有个,非常好用,效果如下:succ views [| comments](#waline) ## 前言[#](#前言) OIer 都知道,洛谷中有个 [Markdown 插件 ↗](https://www.luogu.com.cn/article/70w8j2pj "插件 README"),非常好用,效果如下: 这是一个提示 我是提示内容。 我是父容器 我是一些文字。 我是子容器 1 我是内容 1。 我是一些文字。 我是子容器 2 我是子容器 3 我是内容 2。 我是一些文字。 大家好啊,我是说的道理。 ——otto 居左内容。 居中内容。 居右内容。 源码: ``` :::info[这是一个提示] 我是提示内容。 ::: :::::warning[我是父容器] 我是一些文字。 ::::success[我是子容器 1]{open} 我是内容 1。 :::: 我是一些文字。 ::::success[我是子容器 2]{open} :::error[我是子容器 3]{open} 我是内容 2。 ::: :::: 我是一些文字。 ::::: :::epigraph[——otto] 大家好啊,我是说的道理。 ::: :::align{left} 居左内容。 ::: :::align{center} 居中内容。 ::: :::align{right} 居右内容。 ::: ``` markdown 还有更多…… 尽管 [安知鱼主题 ↗](https://docs.anheyu.com) 自带很多 [标签外挂 ↗](https://hexo.anheyu.com/posts/d50a.html),但仍然无法满足复制洛谷文章到博客编写习惯性的需求,于是,我**全网首发**了在 Hexo 中使用洛谷 Md 插件教程。 闲话 由于不良习惯,我的所有 Markdown 文章编写均遵循洛谷的 [专栏全站推荐规范 ↗](https://help.luogu.com.cn/rules/academic/article-standard)、[洛谷主题库题解规范 ↗](https://help.luogu.com.cn/rules/academic/solution-standard)和[如何用 Markdown 和 LaTeX 写一篇排版整齐的题解? ↗](https://help.luogu.com.cn/rules/academic/guide/solution) ## 方法[#](#方法) 知其然,知其所以然 用 Javasript 自定义 Hexo 的 markdown 解析,用正则匹配把标识等进行匹配,转换为 Html,最后由 Css 完成样式。 ## 实现[#](#实现) 详情 本教程以 anzhiyu 主题为例,其他主题亦可,视情况更改 Css 文件目录和引用方式,参见你的博客主题的文档_以后可能会更新_下这篇文章,搞个多主题支持。 首先,在博客中新建 Css (`~/themes/···(主题名称)/source/css/custom_marked.css`)粘贴以下代码并引入(Anzhiyu 主题可以在 config.yml 中的 Inject.head 配置项中引入)。 ``` .align-left { text-align: left !important; } .align-center { text-align: center !important; } .align-right { text-align: right !important; } .epigraph { width: 40%; margin-left: 60%; } .epigraph > :last-child { margin-top: 0; border-top: 1px solid #888; text-align: right; } summary { list-style: none; -webkit-user-select: none; user-select: none; outline: 0; margin: 0; position: relative; padding-left: 24px; font-weight: 700; list-style: none; display: list-item; min-height: 1em; } .foldable { padding: 0.5em 1em; margin: 1em 0 1em 0.2em; border-left-width: 5px; border-left-style: solid; overflow: hidden; } .foldable.info { border-left-color: rgb(52, 152, 219); } .foldable.warning { border-left-color: rgb(255, 193, 22); } .foldable.success { border-left-color: rgb(82, 196, 26); } .foldable.error { border-left-color: rgb(231, 76, 60); } .foldable.bug { border-left-color: rgb(231, 76, 60); } .foldable.flask { border-left-color: rgb(155, 89, 182); } details.info > summary { color: rgb(52, 152, 219); } details.warning > summary { color: rgb(255, 193, 22); } details.success > summary { color: rgb(82, 196, 26); } details.error > summary { color: rgb(231, 76, 60); } details.bug > summary { color: rgb(231, 76, 60); } details.flask > summary { color: rgb(155, 89, 182); } details.info > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } details.success > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } details.warning > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } details.error > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } details.bug > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } details.flask > summary::before { -webkit-mask-image: url('data:image/svg+xml;utf8,'); mask-image: url('data:image/svg+xml;utf8,'); } summary::before { content: ""; background-color: currentcolor; -webkit-mask-size: contain; mask-size: contain; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; margin-right: 8px; } summary:after { content: ""; background-color: currentcolor; -webkit-mask-size: contain; mask-size: contain; mask-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20256%20512%22%3E%3Cpath%20d%3D%22M246.6%20278.6c12.5-12.5%2012.5-32.8%200-45.3l-128-128c-9.2-9.2-22.9-11.9-34.9-6.9s-19.8%2016.6-19.8%2029.6l0%20256c0%2012.9%207.8%2024.6%2019.8%2029.6s25.7%202.2%2034.9-6.9l128-128z%22%2F%3E%3C%2Fsvg%3E"); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; position: absolute; right: 0; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; transition: transform 0.2s ease; } details[open] > summary::after { transform: translateY(-50%) rotate(90deg); } pre code.hljs { display: block; overflow-x: auto; padding: 1em; } code.hljs { padding: 3px 5px; } code[class*="language-"], pre { background: #fefefe; color: #383a42; font-family: Fira Code, Fira Mono, Menlo, Consolas, DejaVu Sans Mono, monospace; direction: ltr; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; line-height: 1.5; -moz-tab-size: 2; -o-tab-size: 2; tab-size: 2; -webkit-hyphens: none; -moz-hyphens: none; -ms-hyphens: none; hyphens: none; } code[class*="language-"]::-moz-selection, code[class*="language-"] *::-moz-selection, pre *::-moz-selection { background: #e5e5e6; color: inherit; } code[class*="language-"]::selection, code[class*="language-"] *::selection, pre *::selection { background: #e5e5e6; color: inherit; } pre { padding: 1em; margin: 0.5em 0; overflow: auto; border-radius: 0.3em; } :not(pre) > code[class*="language-"] { padding: 0.2em 0.3em; border-radius: 0.3em; white-space: normal; } .copy-button[data-v-a7061ca4] { position: absolute; top: 0.5em; right: 0.5em; padding: 0.6em; display: flex; align-items: center; justify-content: center; transition: 0.2s ease-in-out opacity, 0.2s ease-in-out color, 0.2s ease-in-out background-color; opacity: 0; background-color: transparent; border: none; border-radius: 4px; cursor: pointer; color: #555; } .code-container { margin: 1rem 0; position: relative; border-radius: 0.3em; } .code-container:hover > .copy-button { opacity: 1; } .code-container:hover > .copy-button:hover { background-color: #ddd; } h1 { font-size: 2em; margin: 0.67em 0; } h1 { margin: 1.5rem 0 1rem; font-size: 2em; padding-bottom: 0.1em; border-bottom: solid 1px #d8d8d8; } h2 { margin: 1.2rem 0 1rem; font-size: 1.5em; padding-bottom: 0.1em; border-bottom: solid 1px #d8d8d8; } h3 { margin: 1.2rem 0 1rem; font-size: 1.2em; } h4 { margin: 1rem 0; font-size: 1.1em; } h5 { margin: 1rem 0; font-size: 1em; } h6 { margin: 1rem 0; font-size: 1em; color: #666; } img { max-width: 100%; } ul, ol { padding-left: 2em; } li + li { margin-top: 0.2em; } li.task-list-item { position: relative; list-style-type: none; } li.task-list-item > input:first-child { position: absolute; left: -1.5em; top: 55%; transform: translateY(-50%); padding: 0; margin: 0; } hr { margin: 1em 0; height: 0; border: none; border-bottom: solid 1px #eee; } a { text-decoration: none; transition: filter 0.1s ease; color: rgb(var(--lcolor--link, 52, 152, 219)); cursor: pointer; } table { border-collapse: collapse; border-spacing: 0; display: block; width: 100%; overflow: auto; word-break: keep-all; margin: 10px; font-variant-numeric: tabular-nums; } th, td { border: 1px solid #ddd; padding: 6px 13px; } blockquote { padding: 10px 20px; margin: 0 0 20px; border-left: 5px solid #eee; } a { background-color: transparent; } ``` css 然后直接在 `~/themes/···(主题名称)/scripts` 中新建 custom\_marked.js(也可以是别的名字),粘贴以下代码即可,**不用引入**。 ``` const allowedFoldableTypes = new Set(['info', 'warning', 'success', 'error', 'bug', 'flask']); function renderMarkdown(content) { return hexo.render.renderSync({ text: content.trim(), engine: 'markdown' }); } function renderCustomBlock(blockType, title, opt, body) { const type = blockType.toLowerCase(); const content = renderMarkdown(body.trim()); if (type === 'align') { const dir = title ? title.trim() : 'left'; return `\n
\n${content}\n
\n`; } if (type === 'epigraph') { const author = title ? `

${title}

` : ''; return `\n
\n${content}${author}\n
\n`; } if (allowedFoldableTypes.has(type)) { const openAttr = opt && opt.includes('open') ? ' open' : ''; const summary = title ? title.trim() : '详情'; return `\n
\n ${summary}\n
\n${content}\n
\n
\n`; } return null; } function parseCustomBlocks(content) { const lines = content.split(/\r?\n/); const root = { type: 'root', children: [] }; const stack = [root]; let codeFence = null; const openRule = /^\s*(:{3,})([a-zA-Z]\w*)(?:\s*\[([^\]]*)\])?(?:\s*\{([^}]*)\})?\s*$/; const closeRule = /^\s*(:{3,})\s*$/; for (const line of lines) { const fenceMatch = line.match(/^\s*(`{3,}|~{3,})/); if (fenceMatch) { const fence = fenceMatch[1]; if (!codeFence) { codeFence = fence; } else if (codeFence === fence) { codeFence = null; } stack[stack.length - 1].children.push({ type: 'text', value: line }); continue; } if (codeFence) { stack[stack.length - 1].children.push({ type: 'text', value: line }); continue; } const openMatch = line.match(openRule); if (openMatch) { const level = openMatch[1].length; const blockType = openMatch[2].toLowerCase(); const title = openMatch[3] || ''; const opt = openMatch[4] || ''; const node = { type: 'block', level, blockType, title, opt, children: [] }; stack[stack.length - 1].children.push(node); stack.push(node); continue; } const closeMatch = line.match(closeRule); if (closeMatch) { const level = closeMatch[1].length; if (stack.length > 1 && stack[stack.length - 1].level === level) { stack.pop(); continue; } } stack[stack.length - 1].children.push({ type: 'text', value: line }); } return renderNode(root); } function renderNode(node) { if (node.type === 'root') { return node.children.map(renderNode).join('\n'); } if (node.type === 'text') { return node.value; } if (node.type === 'block') { const inner = node.children.map(renderNode).join('\n'); const customHtml = renderCustomBlock(node.blockType, node.title, node.opt, inner); if (customHtml !== null) { return customHtml; } const start = `${':'.repeat(node.level)}${node.blockType}${node.title ? `[${node.title}]` : ''}${node.opt ? `{${node.opt}}` : ''}`; const end = ':'.repeat(node.level); return `${start}\n${inner}\n${end}`; } return ''; } hexo.extend.filter.register('before_post_render', data => { if (typeof data.content !== 'string') return data; hexo.log.debug('custom_marked before_post_render', data.source || data.path || data.title || 'unknown'); data.content = parseCustomBlocks(data.content); return data; }); ``` javascript 为什么不用引入? 与前面引入的 Css 不同的是,任意主题的目录 `~/themes/···(主题名称)/scripts` 功能都都一样,Hexo 解析时都会运行改此目录下的**所有** Javascript 文件。 可能的错误 一不小心放到了 `~/themes/anzhiyu/source/js/custom_marked.js` 里。唐 ## 完结[#](#完结) ``` hexo new "plugin-test" hexo cl&&hexo g&&hexo s ``` bash 赶紧在文章里尝试并体验一下吧!是不是很好用?如果有什么建议,可以在[评论区](#post-comment)告诉我哦! --- ## MDX Components: User & Advanced URL: https://blog.rusin7.com/en/article/mdx-components How to use built-in content components (Aside/Tabs, etc.) and advanced widgets (LinkPreview/GithubCard, etc.). Jan 11, 2026 / Update Jan 11, 2026 1 分钟 en [markdown](/tags/markdown) # MDX Components: User & Advanced > How to use built-in content components (Aside/Tabs, etc.) and advanced widgets (LinkPreview/GithubCard, etc.). views [| comments](#waline) ## 1\. Use MDX (Required)[#](#1-use-mdx-required) `.md` cannot `import` components. Use `.mdx` (e.g. `src/content/blogs//index.mdx`). ## 2\. User Component Examples[#](#2-user-component-examples) - [A](#tab-panel-2) - [B](#tab-panel-3) Panel A content Panel B content Hidden content goes here. ## 3\. Advanced Component Examples[#](#3-advanced-component-examples) ### GitHub Card[#](#github-card) [ rusin-dev / astro-theme-cyanwind Waiting for api.github.com... ??? ??? ??? ????? ](https://github.com/rusin-dev/astro-theme-cyanwind) ### Link Preview[#](#link-preview) ![Astro - Build the web you want.](https://astro.build/og/astro.jpg)[ Astro builds fast content sites, powerful web applications, dynamic server APIs, and everything in-between. (astro.build) ](https://astro.build/) ### QR Code[#](#qr-code) ### Image Group (masonry-like row)[#](#image-group-masonry-like-row) ![Image A](https://picr2.axi404.top/1767811093734_image.webp) ![Image B](https://picr2.axi404.top/1767811093734_image.webp) ### Embedded Video[#](#embedded-video) --- ## 笔记——树形动态规划 URL: https://blog.rusin7.com/en/article/notes-of-dp-on-trees 若如图所示,当前dfs至点u,则转移方程得 Jun 7, 2026 2 分钟 [笔记](/tags/笔记) / [c++](/tags/c++) # 笔记——树形动态规划 > 若如图所示,当前dfs至点u,则转移方程得 views [| comments](#waline) 详情 **设计状态**:用 dpu,0/1dp\_{u,0/1}dpu,0/1​ 表示以 uuu 为根的子树的最大快乐指数。 **答案**:max⁡{dproot,1,dproot,0}\\max\\{dp\_{root,1},dp\_{root,0}\\}max{dproot,1​,dproot,0​}。 ## [P1352 没有上司的舞会 ↗](https://www.luogu.com.cn/problem/P1352)[#](#p1352-没有上司的舞会) 若如图所示,当前 dfs 至点 uuu,则转移方程如下: dpu,0←dpu,0+max⁡(dpv,0,dpv,1)dp\_{u,0}\\leftarrow dp\_{u,0}+\\max(dp\_{v,0},dp\_{v,1})dpu,0​←dpu,0​+max(dpv,0​,dpv,1​) dpu,1←dpu,1+dpv,0dp\_{u,1}\\leftarrow dp\_{u,1}+dp\_{v,0}dpu,1​←dpu,1​+dpv,0​ ![1](https://cdn.luogu.com.cn/upload/image_hosting/dizzn16u.png) 所以可以写出以下代码: ``` #include using namespace std; int n,r[6005],in[6005],rt,dp[6005][2]; vectorg[6005]; void dfs(int u){ for(int v:g[u]){ dfs(v); dp[u][0]+=max(dp[v][0],dp[v][1]); dp[u][1]+=dp[v][0]; } dp[u][1]+=r[u]; } int main(){ cin>>n; for(int i=1;i<=n;++i){ cin>>r[i]; } for(int i=1;i>u>>v; g[v].push_back(u); in[u]=1; } for(int i=1;i<=n;++i){ if(!in[i]){ rt=i; break; } } dfs(rt); cout< using namespace std; int n,in[5005],dp[5005][2],rt; vectorg[5005]; void dfs(int u){ dp[u][0]=0; dp[u][1]=1; for(int v:g[u]){ dfs(v); dp[u][0]+=dp[v][1]; dp[u][1]+=min(dp[v][0],dp[v][1]); } } int main(){ cin>>n; for(int i=1;i<=n;++i){ int u,k,v; cin>>u>>k; u++; for(int j=1;j<=k;++j){ cin>>v; v++; g[u].push_back(v); in[v]=1; } } for(int i=1;i<=n;++i){ if(!in[i]){ rt=i; break; } } dfs(rt); cout< using namespace std; int n,a[16005],dp[16005],ans=INT_MIN; vectorg[16005]; void dfs(int u,int fa){ dp[u]=a[u]; for(int v:g[u]){ if(v!=fa){ dfs(v,u); dp[u]+=max(0,dp[v]); } } } int main(){ cin>>n; for(int i=1;i<=n;++i)cin>>a[i]; for(int i=1;i>u>>v; g[u].push_back(v); g[v].push_back(u); } dfs(1,0); for(int i=1;i<=n;++i){ ans=max(dp[i],ans); } cout< 本文讲述了如何使用 C++ 完成洛谷的 P13361 \[GCJ 2011 Qualification\] Bot Trust」水落溪流浅浅,思路清晰、排版精美 views [| comments](#waline) 本题解被打回无法重新提交嘤嘤嘤 ## 题意理解[#](#题意理解) ### 形式化翻译[#](#形式化翻译) 题目翻译有点难懂(其实是本蒟蒻懒得看),让本蒟蒻来形式化一下: 对于每组测试用例,有 nnn 个执行任务的机器人和对应的按钮, 222 个机器人需**依次**按下自己对应的按钮,求计算 222 个机器人按完按钮所需的最少时间。 ### 注意事项[#](#注意事项) - 必须严格按照给定顺序操作,后一个按钮的操作必须在前一个完成后才能开始。 - 机器人可同时移动但**不能同时执行**按键操作。 ## 解题思路[#](#解题思路) ### 状态跟踪[#](#状态跟踪) 需使用记录两个机器人的当前位置 posoposoposo 和 posbposbposb ( posoposoposo 对应`Orange`, posbposbposb 对应`Blue`)和各自上次操作完成的时间 timeotimeotimeo 和 timebtimebtimeb ,以及整个流程的总时间 sss 。 对于每组测试用例,**千万不要忘记**对 posoposoposo 、 posbposbposb 、 timeotimeotimeo 和 timebtimebtimeb 进行**初始化**! ### 操作逻辑[#](#操作逻辑) - 对每个命令,先确定执行的机器人(判断输入为`O`或`B`)。 - 计算从到达目标位置的时间 ∣ai−poso/posb∣×1|a\_i-poso/posb| \\times1∣ai​−poso/posb∣×1 。 - 确定实际完成时间:取到达时间和当前总时间的最大值(保证顺序性),再加 111 秒按键时间,用公式表达即为: > ntime←max⁡{timeo+∣ai−poso/posb∣,s}ntime \\leftarrow \\max\\{timeo+|a\_i-poso/posb|,s\\}ntime←max{timeo+∣ai​−poso/posb∣,s} - 更新机器人位置、对应完成时间和总时间。 ## 代码实现[#](#代码实现) ``` #include using namespace std; // 存储每个命令的结构体:机器人类型和目标位置 struct Command{ char robot; int pos; }a[100]; int t,n,poso,posb,timeo,timeb,s,p,ntime; char c; // 初始化函数:重置机器人初始状态 void init(){ poso=1; // 初始位置均为1 posb=1; timeo=0; // 初始时间为0 timeb=0; s=0; // 总时间初始为0 } int main(){ cin>>t; for (int k=1;k<=t;k++) { cin>>n; for (int i= 0;i>a[i].robot>>a[i].pos; } init(); // 初始化状态 for(int i=0;i 本文讲述了如何使用 C++ 完成洛谷的 题解:P14702 \[ICPC 2024 Tehran R\] Boat,思路清晰、排版精美 views [| comments](#waline) [题目传送门 ↗](https://www.luogu.com.cn/problem/P14702) 贪心,细节较多。 ## 思路分析[#](#思路分析) 先特判无解情况。 提示 - 如果某个重量大于最大载重量 www,输出 `−1`,结束。 - 如果最轻的两个人重量之和超过了 www,即**无人**可以当船夫,输出 `−1`,结束。 否则**一定**有解,尽量让**两人配对上船**,为了用最少次数,先 sort 从小到大排序,再让最轻的人作为船夫,分为两种情况: - 如果 ai+a1≤wa\_i+a\_1 \\leq wai​+a1​≤w,可以和最轻的人一起上船,可载两人。这样运送要 222 次,ans←ans+2ans \\leftarrow ans+2ans←ans+2。 - 否则,不可以和最轻的人一起上船,只载一人。这样运送要 444 次,ans←ans+4ans \\leftarrow ans+4ans←ans+4。 最后船夫不回来,所以输出 ans−1ans-1ans−1。 ## 代码[#](#代码) 按思路写即可,注意细节,这里不放了。 ## 结语[#](#结语) 感谢您的阅读! --- ## 题解:P14730 [ICPC 2022 Seoul R] Palindrome Type URL: https://blog.rusin7.com/en/article/p14730-sol 本文讲述了如何使用 C++ 完成洛谷的 P14730 [ICPC 2022 Seoul R] Palindrome Type,思路清晰、排版精美 ![题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 30, 2026 2 分钟 [题解](/tags/题解) / [c++](/tags/c++) # 题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type > 本文讲述了如何使用 C++ 完成洛谷的 P14730 \[ICPC 2022 Seoul R\] Palindrome Type,思路清晰、排版精美 views [| comments](#waline) [**纯享阅读区** ↗](https://www.luogu.com.cn/article/twhfrn73 "纯享阅读区") [题目传送门 ↗](https://www.luogu.com.cn/problem/P14730 "P14730 [ICPC 2022 Seoul R] Palindrome Type") ## 总体分析[#](#总体分析) **核心**:修改字符串 sss 使其成为回文串,记最小次数为 kkk,如果 k≤3k\\leq3k≤3,输出 kkk,否则输出 `-1` 。 因此,可以从 k\=0∼3k=0\\sim3k\=0∼3 依次进行 DFS 搜索,只要有一次成功,输出 kkk,结束。 ## 思路引导[#](#思路引导) {% note warning flat %} **提问** 如何 DFS **搜索**修改过程算出 kkk? {% endnote %} {% note success flat %} **DFS 函数** 使用 [双指针 ↗](https://oi-wiki.org/misc/two-pointer/)。 当 l 本文讲述了如何使用 C++ 完成洛谷的 P14731 \[ICPC 2022 Seoul R\] Parentheses Tree,思路清晰、排版精美 views [| comments](#waline) * * * [题目传送门 ↗](https://www.luogu.com.cn/problem/P14731 "P14731 [ICPC 2022 Seoul R] Parentheses Tree") ## 前置知识[#](#前置知识) STL 中的 stack 容器提供了一众成员函数以供调用,其中较为常用的有: - 定义 - 头文件 \\color{green}\\textbf{}。 - 元素访问 - `st.top()` 返回栈顶。 - 修改 - `st.push()` 插入传入的参数到栈顶。 - `st.pop()` 弹出栈顶。 - 容量 - `st.empty()` 返回是否为空。 - `st.size()` 返回元素数量。 部分内容来自 [栈 - OI Wiki ↗](https://oi-wiki.org/ds/stack/ "栈 - OI Wiki")。 ## 总体分析[#](#总体分析) **核心**:用栈匹配括号并在叶节点累加距离。 ## 思路引导[#](#思路引导) 提问 如何对左括号进行判断是否为叶节点? 成功 当 sis\_isi​ 为 `(` 时,如果栈非空,将栈顶替换为 false,再将 true 入栈。 提问 如何将答案进行累加? 成功 当 sis\_isi​ 为 `)` 时,如果栈顶 `(` 是叶子节点,先累加栈内元素数量,再弹出栈顶。 警告 不开 long long 见祖宗。 ## 核心代码[#](#核心代码) ``` cin>>s; for(char c:s){ if(c=='('){ if(st.size()){ st.pop(); st.push(false); }//替换操作 st.push(true); }else{ if(st.top()){ ans+=st.size()-1; }//累加栈内元素数量 st.pop();//弹出栈顶 } } cout< 本文讲述了如何使用 C++ 完成洛谷的 P8506 标题计数,思路清晰、排版精美 views [| comments](#waline) ## 前言[#](#前言) 本篇题解适合**刚学[字符串 ↗](https://www.luogu.com.cn/problem/list?type=luogu&page=1&tag=357)和[模拟 ↗](https://www.luogu.com.cn/problem/list?type=luogu&difficulty=1&page=1&tag=1)的同学**阅读,语言浅显易懂。谁让作者是个蒟蒻呢。 ## 题目分析[#](#题目分析) **核心条件**: - 第一个非空格字符**必须**是井号 `#`。 - 井号后面**必须**紧跟着**至少一个**空格且**不能**有多个井号相连(如 `##`)。 - 在井号后面的空格后**必须**有长度不为 000 的句子。 ## 思路引导[#](#思路引导) 提问 如何输入一行**含空格**的字符串? 成功 使用 string 类型自带的 `getline()` 。 提问 如何判断字符串是否为一级标题? 成功 联系我们刚分析完的核心条件,可以进行**模拟**。具体如下: - 首先,假设读入的字符串 sss 不是一级标题,flagflagflag 为 false 。再将 sss 从头到尾扫一遍。 - 如果 sis\_isi​ 是空格,直接跳过。 - 否则如果 flagflagflag 为 true ,说明已经满足核心条件中的 1、2 点,且现在 sis\_isi​ 不为空格,也满足第 3 点,计数器 +1+1+1。 - 否则如果 sis\_isi​ 是非 `#` 字符,sss 必定不是一级标题,跳出循环。 - 否则如果 sis\_isi​ 是 `#` 字符且满足核心条件中的 1、2 点,flagflagflag 为 true 。 - 否则 sss 必定不是一级标题,跳出循环。 ## 完整代码[#](#完整代码) ``` #include using namespace std; int n,pos,cnt; // cnt用于计数符合条件的标题 bool flag; // 标记是否满足标题的前置条件 string s; int main() { cin>>n; cin.ignore(); // 忽略n后面的换行符 while(n--) { getline(cin,s); // 读取一整行文本 flag=false; // 初始化标记 for(int i=0; i 本文讲述了如何使用 C++ 完成洛谷的 P8534 「Wdoi-2」比赤色更红的梦,思路清晰、排版精美 views [| comments](#waline) [题目传送门 ↗](https://www.luogu.com.cn/problem/P8534) ## 题意分析[#](#题意分析) **核心**:对于每组数据,判断 xxx 是否 ≥3\\ge 3≥3 或 ≥5\\ge 5≥5 并对应地将残机 +1+1+1,判断 sss 是否 ≥10000000\\ge 10000000≥10000000、≥20000000\\ge 20000000≥20000000、≥40000000\\ge 40000000≥40000000 或 ≥60000000\\ge 60000000≥60000000 并对应地将残机 +1+1+1。 ## 思路引导[#](#思路引导) 提问 如何处理多组数据? 成功 使用 `while` 循环语句,每次将 t−1t-1t−1,因为 t\=0t=0t\=0 时布尔值为 000, 即 false,所以将会跳出循环,此时循环语句正好执行 ttt 次。格式如下: ``` while(t--/*布尔表达式*/){ //执行____ } ``` cpp 提问 如何对 xxx 和 sss 的值进行判断? 成功 使用 `if` 分支语句,格式如下: ``` //普通版: if(/*布尔表达式*/){ //执行____ } //压行版: if(/*布尔表达式*/)//执行____(限一句) ``` cpp 警示 - 如果你将 sss 开 int ,那么你将喜提 WA\\color{E74C3C}{\\text{WA}}WA,25pts\\color{E74C3C}{\\text{25pts}}25pts。请注意观察数据范围! 别问我是[怎么知道的 ↗](https://www.luogu.com.cn/record/236917936) - 别忘了每次将 ansansans 初始化为 222。 ## 核心代码[#](#核心代码) 只提供 `while` 循环语句内的代码。 ``` ans=2; cin>>x>>s; if(x>=3)ans++; if(x>=5)ans++; if(s>=10000000)ans++; if(s>=20000000)ans++; if(s>=40000000)ans++; if(s>=60000000)ans++; cout< 我将背后的时间裁剪、折叠、蜷曲,揉捻成天上朵朵白云。 views [| comments](#waline) 1111 居中内容。 ## 追忆[#](#追忆) 我常常追忆过去。 生命瞬间定格在脑海。我将背后的时间裁剪、折叠、蜷曲,揉捻成天上朵朵白云。 云朵之间亦有分别:积云厚重,而卷云飘渺。生命里震撼的场景掠过我的思绪便一生无法忘怀,而更为普通平常的记忆在时间的冲刷下只留下些许残骸。追忆宛如入梦,太过清楚则无法愉悦自己的幻想,过分模糊却又坠入虚无。只有薄雾间的山水,面纱下的女子,那恰到好处的朦胧,才能满足我对美的苛求。 追忆总在不经意间将我裹进泛黄的纸页里。分别又重聚的朋友,推倒又重建的街道,种种线索协助着我从一个具体的时刻出发沿时间的河逆流而上。曾经的日子无法重来,我只不过是一个过客。但我仍然渴望在每一次追忆之旅中留下闲暇时间,在一个场景前驻足,在岁月的朦胧里瞭望过去的自己,感受尽可能多的甜蜜。美好的时光曾流过我的身体,我便心满意足。 过去已经凝固,我带着回忆向前,只是时常疏于保管,回忆也在改变着各自的形态。这给我的追忆旅程带来些许挑战。 我该在哪里停留?我问我自己。 --- ## 在 VS code 上远程管理 Github 仓库并自动化部署项目 URL: https://blog.rusin7.com/en/article/remote-github-repo-on-vs-code 如果GitHub远程是没有提交的空仓库然后再绑定哦。 Apr 19, 2026 7 分钟 [vs code]() / [git](/tags/git) / [nodejs](/tags/nodejs) # 在 VS code 上远程管理 Github 仓库并自动化部署项目 > 如果GitHub远程是没有提交的空仓库然后再绑定哦。 views [| comments](#waline) ## 如果 GitHub 远程是没有提交的空仓库[#](#如果-github-远程是没有提交的空仓库) ``` git init git add -A git commit -m "🔄️ init:初始化 main 源码分支" git checkout -b main ``` bash 然后再绑定哦。 ## 绑定本地仓库到你已有的 GitHub 远程仓库[#](#绑定本地仓库到你已有的-github-远程仓库) 先把本地和远程仓库建立连接,Ctrl+Shift+\`调出 VS code 终端直接执行: ``` git remote add origin https://github.com/你的用户名/仓库名.git ``` bash **验证绑定成功**: ``` git remote -v ``` bash 终端输出下面这样,就代表绑定成功: ``` origin git@github.com:xxx/xxx.git (fetch) origin git@github.com:xxx/xxx.git (push) ``` bash {% note info flat %} 报错 `fatal: remote origin already exists`:说明之前绑过别的,先执行 `git remote remove origin` 解除绑定,再重新执行上面绑定命令即可。 {% endnote %} ## 拉取远程旧 main 分支内容,做安全备份(如果你的仓库原来有 main 分支,可选)[#](#拉取远程旧-main-分支内容做安全备份如果你的仓库原来有-main-分支可选) 远程 {% label main red %} 全是旧的 {% label dist red %} 文件,我们先把它拉到本地,备份成一个旧分支,绝对不覆盖本地源码,全程安全兜底。 ``` git fetch origin git branch old-main origin/main ``` bash 执行完,你本地就多了一个 {% emp old-main %} 备份分支,以前手动上传的所有文件全部永久保留,后续操作完全不会动它。 ## 重置本地 main 分支为纯净源码分支[#](#重置本地-main-分支为纯净源码分支) 你的 `.gitignore` 已经写好了 `dist`,会自动忽略打包文件夹,不会把 `dist` 提交到 {% label main red %} 分支。 ``` git checkout main git add . git commit -m "🔄️ init:初始化 main 源码分支" ``` bash ## 推送全新源码 main 分支[#](#推送全新源码-main-分支) 如果 {% label main red %} 分支已经有冲突文件: ``` git push -f origin main ``` bash 否则: ``` git push origin main ``` bash {% tip success %}GitHub 远程 {% label main red %} 分支:已经全部是你的项目源码,`dist` 文件夹被 .gitignore 自动忽略,完全不会上传到 {% label main red %}!{% endtip %} * * * ## 新建 gh-pages 分支,只存放静态文件[#](#新建-gh-pages-分支只存放静态文件) 这一步专门创建部署分支,全程独立,和 {% label main red %} 分支完全隔离,只存放打包后的 `dist` 静态文件。 ``` pnpm build cd dist && git init && git add . && git commit -m "init gh-pages" && git push -f git@github.com:你的用户名/仓库名.git HEAD:gh-pages && cd .. ``` bash {% tip success %}GitHub 远程 {% label gh-pages red %} 分支:里面只有 `dist` 静态网页文件,无任何源码,专门用于 GitHub Pages 网站部署。{% endtip %} * * * ## 日常开发[#](#日常开发) 你以后每次修改完代码,更新网页,只需要严格按这个顺序走,再也不用手动上传文件: ### Vite 项目[#](#vite-项目) #### 1\. 开发修改源码(全程在 main 分支)[#](#1-开发修改源码全程在-main-分支) 你改完源码后,更新到 GitHub 源码仓库: ``` git add . git commit -m "✨ UppubDatetime: 更新源码" git push origin main ``` bash #### 2\. 打包生成最新的 dist 文件[#](#2-打包生成最新的-dist-文件) 在 main 分支终端执行打包命令(根据你的项目,你的是 vite 项目) ``` npm run build # 或 pnpm build ``` bash 执行完,本地 `dist` 文件夹就会更新为最新打包文件。 {% note primary flat %} 回到主项目根目录,执行这 2 条全局 git 配置,永久关闭这个烦人的换行符警告: ``` git config core.autocrlf true git config core.safecrlf false ``` bash {% endnote %} #### 3\. 一键更新 gh-pages 部署网页[#](#3-一键更新-gh-pages-部署网页) ``` npm run build # 或 pnpm build cd dist && git init && git add . && git commit -m "uppubDatetime site" && git push -f git@github.com:你的用户名/你的仓库名.git HEAD:gh-pages && cd .. ``` bash - 打包最新静态文件 - 一键纯净推送 gh-pages,无任何多余文件 ### NextJs 项目[#](#nextjs-项目) #### 每次写完代码 →\\to→ 推源码(main)[#](#每次写完代码-to-推源码main) Ctrl+Shift+\` 打开终端,直接运行: ``` git add . git commit -m "更新项目源码" git push origin main ``` bash {% folding green, ✅ 作用 %} 把你的代码推送到小号 {% hideInline 看什么看,查\*\*\*\*\*\*,#FF7242,#fff %} 的 {% label main red %} 分支(你已经配置好锁死小号,直接推就行) {% endfolding %} ### 要发布网页 →\\to→ 推静态文件(gh-pages)[#](#要发布网页-to-推静态文件gh-pages) 还是在根目录,直接复制这一条完整命令运行: ``` npm run build && cd out && git add . && git commit -m "更新网页" && git push -f https://ru-sin@github.com/ru-sin/用户名.git HEAD:gh-pages && cd .. ``` bash {% note success flat %} 这条命令会自动 - 打包生成最新 `out` - 提交网页文件 - 强制推送到小号 {% label gh-pages red %} 分支 - 退回根目录 {% endnote %} * * * ## 高级做法(2 选 1)[#](#高级做法2-选-1) ### 推送 main 源码后自动推送 gh-pages 分支[#](#推送-main-源码后自动推送-gh-pages-分支) 访问 /settings/actions,下滑找到 `Workflow permissions`,勾选 Read and write permissions,点击 `Save` 就好了。 {% label main red %} 分支新建 `.github/workflows/deploy.yml`,直接复制代码如下: ``` name: 自动部署到 gh-pages on: push: branches: - main # 推送到 main 分支就自动触发 jobs: deploy: runs-on: ubuntu-latest steps: - name: 拉取代码 uses: actions/checkout@v4 with: persist-credentials: false - name: 安装依赖 run: npm install - name: 编译生成 out 文件夹 run: npm run build - name: 部署到 gh-pages uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./out ``` yml 这样就不需要推静态文件({% label gh-pages red %})分支了,直接推 {% label main red %} 即可。 ### build 后一行命令部署 dist[#](#build-后一行命令部署-dist) 安装工具。 ``` npm install gh-pages --save-dev ``` bash 在 `package.json` 里添加部署脚本。 ``` { "scripts": { "deploy": "gh-pages -d dist" } } ``` json 部署命令,可以自动部署到 gh-pages 分支。 ``` npm run build npm run deploy ``` bash {% tip success %}成功!{% endtip %} --- ## Rusin note Project Recommend URL: https://blog.rusin7.com/en/article/rusin-note Recommend a lightweight Python project for server deployment. Welcome to submit PRs and join the development! ![Rusin note Project Recommend](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) ![Blur image](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) Aug 13, 2026 11 分钟 en [建站](/tags/建站) / [github](/tags/github) / [开源项目](/tags/开源项目) / [教程](/tags/教程) # Rusin note Project Recommend > Recommend a lightweight Python project for server deployment. Welcome to submit PRs and join the development! views [| comments](#waline) [ rusin-dev / rusin-note Waiting for api.github.com... ??? ??? ??? ????? ](https://github.com/rusin-dev/rusin-note) Welcome to Star and Fork this project! This article may not be updated in time. Please refer to the [README ↗](https://github.com/rusin-dev/rusin-note) for the latest information. ![屏幕截图](/images/screen.png) ## Features[#](#features) - **Cloud clipboard that works out of the box**: A lightweight Flask implementation for VPS or serverless (Vercel / AWS Lambda) deployment, letting you save and access text quickly from any browser. - **Public and private notes**: Use random short paths for public notes, or keep private note lists under guest accounts for both temporary sharing and personal storage. - **Secure share links**: Generate random-token share links for user notes, with optional write-back support for simple cross-device collaboration. - **Markdown and LaTeX rendering**: Read-only pages and the benben feed support Markdown and KaTeX math, making the app useful for code snippets, notes, documentation, and formulas. - **Benben feed**: A built-in lightweight feed where logged-in users can post and anonymous users can read, with live preview, paginated loading, and post cooldowns. - **Multi-language UI**: Simplified Chinese and English are built in, with manual switching and browser-language fallback. - **Deployment-friendly configuration**: Common options live in `config.json`, including note expiration, session timeout, password policy, trusted proxy IP handling, and HTTPS cookies. For serverless deployment, data can go to external storage (Upstash Redis / Neon PostgreSQL), surviving cold starts. - **Practical baseline protection**: Includes CSRF protection, request rate limits, save limits, registration limits, content sanitization, and a proxy-header trust switch for safer public deployments. ## Quick Start[#](#quick-start) ### Requirements[#](#requirements) Python version ≥\\geq≥ 3.10. ### Local Development[#](#local-development) 1. Clone the repository ``` git clone https://github.com/rusin-dev/rusin-note.git cd rusin-note ``` bash 2. Dependency installation ``` pip install -r requirements.txt ``` bash 3. Start the server ``` python3 -m app ``` bash Then open [https://localhost:8080 ↗](https://localhost:8080) to view the result. ### Production Deployment[#](#production-deployment) #### Option 1: Vercel (Serverless, Recommended)[#](#option-1-vercel-serverless-recommended) The repository ships with Vercel configuration (`vercel.json` + `api/index.py`): 1. Import this repository on [Vercel ↗](https://vercel.com) (the Python runtime is auto-detected). 2. Pick a storage backend: - **Neon (PostgreSQL)**: install [Neon ↗](https://vercel.com/marketplace/neon) from the Vercel Storage / Marketplace — Vercel injects `DATABASE_URL` automatically (Vercel KV has been sunset; Neon is the recommended persistent option). - **Upstash Redis**: install Upstash Redis from the Vercel Marketplace and set `KV_REST_API_URL` / `KV_REST_API_TOKEN` manually. Upstash wins if both are set. 3. Add the environment variable `RUSIN_SECRET_KEY` (any long random string, used for session/CSRF signing — **required**; without it login state is lost on each cold start). 4. Deploy. Notes, users, sessions, shares and benben posts are all stored in Neon/Upstash — shared across instances, survives cold starts. Optional: set `REDIS_URL` so rate-limit counters are shared across instances (defaults to per-instance memory). > Note: `config.json` defaults to `trust_proxy_headers: true` and `secure_cookies: true` for serverless platforms. Change them back for local/VPS use if needed. #### Option 2: AWS Lambda (Serverless)[#](#option-2-aws-lambda-serverless) `lambda_handler.py` (Mangum WSGI adapter) is included: 1. Package the repository (including `templates/`, `config.json`, etc.); 2. Handler: `lambda_handler.handler`, with API Gateway proxy integration; 3. Env vars as on Vercel (`KV_REST_API_URL` / `KV_REST_API_TOKEN` / `RUSIN_SECRET_KEY`); 4. Memory ≥ 512MB recommended (Markdown rendering). #### Option 3: VPS / Traditional Server[#](#option-3-vps--traditional-server) Connect to your server, then: 1. Clone the repository ``` git clone https://github.com/rusin-dev/rusin-note.git cd rusin-note ``` bash 2. Dependency installation ``` pip install -r requirements.txt ``` bash 3. Start the server ``` python3 -m app # Run in the background nohup python3 -m app > app.log 2>&1 & ``` bash 4. Configure Nginx (optional) Create a site configuration: ``` sudo nano /etc/nginx/sites-available/rusin-note ``` bash Copy the following content: ``` server { listen 80; server_name _ your_domain.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` nginx > After setting up the Nginx reverse proxy, set `trust_proxy_headers` to `true` in `config.json` so the server trusts the `X-Real-IP` header for rate limiting by the real client IP (disabled by default to prevent header-forging bypasses). ``` # Enable and reload sudo ln -s /etc/nginx/sites-available/rusin-note /etc/nginx/sites-enabled sudo nginx -t && sudo systemctl reload nginx sudo ufw allow 'Nginx Full' ``` bash ### Zeabur Auto Deployment[#](#zeabur-auto-deployment) When deploying from GitHub on Zeabur, the application directory is rebuilt on each deployment. To prevent clipboards, users, share links, and benben posts from being cleared, store runtime data in a persistent volume: 1. Open the current service in your Zeabur project. 2. Go to `Storage` / `Volumes` and create a new Volume. 3. Set the Volume mount path to `/data`. 4. Go to `Environment Variables` and add `RUSIN_DATA_DIR=/data`. 5. Redeploy the service. Do not mount the Volume to the project root, or it may hide the deployed application code. After setup, runtime data is stored under `/data`: ``` /data/notes/ /data/users.json /data/sessions.json /data/shares.json /data/log/ ``` plaintext Benben posts are now persisted to the storage backend (up to `benben.max_posts`, default 200) instead of pure memory. ### Storage Backends (Key for Serverless)[#](#storage-backends-key-for-serverless) The storage layer (`app/storage.py`) provides four backends, selected explicitly via the `RUSIN_STORAGE` env var or auto-detected: | Backend | How to enable | Notes | | --- | --- | --- | | file | default (local/VPS) | Data under RUSIN_DATA_DIR (default: current dir), layout as above | | upstash | set KV_REST_API_URL + KV_REST_API_TOKEN (Upstash Redis REST API) | Data in external KV — shared across instances, survives cold starts; plain HTTPS requests, works on any Python serverless platform | | postgres | set DATABASE_URL (Neon or any PostgreSQL; injected automatically when Neon is attached on Vercel) | Data in PostgreSQL tables (storage_kv / storage_notes); cross-instance mutual exclusion via PG advisory locks | | memory | RUSIN_STORAGE=memory (auto-enabled on serverless platforms without the above) | In-memory only, cleared on restart | Auto-detect priority: explicit `RUSIN_STORAGE` > `KV_REST_API_URL`+`KV_REST_API_TOKEN` (upstash) > `DATABASE_URL` (postgres) > serverless platform (memory) > local (file). - Serverless environments (detected via `VERCEL` / `NETLIFY` / `AWS_LAMBDA_FUNCTION_NAME`) do not start background threads — cleanup runs opportunistically inside requests; logs fall back to stderr (platform log streams). - Set `RUSIN_SECRET_KEY` on serverless platforms; if unset and the backend is persistent (file/upstash/postgres) a key is generated and stored automatically, otherwise a random per-instance key is used. - See `.env.example` for the full env var list. ## Project Structure[#](#project-structure) ``` rusin-note:. │ config.json (configuration) │ contributing.md (collaboration guide) │ Disclaimer-en.md (English disclaimer) │ Disclaimer.md (disclaimer) │ favicon.ico │ README.md │ README_en.md │ requirements.txt (Python dependencies) │ zbpack.json (packaging configuration) │ ├─app (core code) │ │ __init__.py │ │ __main__.py (entry: python3 -m app) │ │ auth.py (password hashing & session auth) │ │ background.py (background cleanup tasks) │ │ config.py (configuration loading & global constants) │ │ extensions.py (Flask extension instances) │ │ i18n.py (multi-language support) │ │ logger.py (logging) │ │ middleware.py (request hooks and rate-limit helpers) │ │ notes.py (note file operations & stats) │ │ store.py (users/sessions/shares/benben data storage) │ │ theme.py (theme and static resource helpers) │ │ utils.py (shared utilities) │ │ wsgi.py (WSGI entry) │ │ │ └─views (blueprints and routes) │ __init__.py (blueprint registration) │ _helpers.py (view helpers) │ auth.py (login and registration) │ benben.py (benben feed) │ home.py (home page) │ share.py (share pages) │ static_routes.py (static and documentation pages) │ user.py (user and user notes) │ world.py (public notes) │ world_short.py (short-link public notes) │ ├─templates (Jinja2 templates) │ │ base.html (base layout) │ │ count.html (statistics page) │ │ disclaimer.html (disclaimer page) │ │ home.html (home page) │ │ │ ├─auth (auth pages) │ ├─benben (benben pages) │ ├─errors (error pages) │ ├─notes (note pages) │ ├─partials (shared partials) │ └─share (share pages) │ ├─image (image assets) │ logo.png │ ├─.github │ │ issue-labeler.yml (Issue label configuration) │ │ │ ├─ISSUE_TEMPLATE (Issue templates) │ └─workflows (GitHub Actions) │ auto-merge.yml (auto-merge) │ check.yml (checks) │ codeql.yml (CodeQL analysis) │ labeler.yml (auto-labeling) │ release.yml (release) │ trigger-fork-sync.yml (trigger fork sync) │ upstream-sync.yml (upstream sync) ``` plaintext ### Configuration Options[#](#configuration-options) - `max_note_size_kb`:Maximum note size (in **KB**), default `512` (0.5 MB). - `sitename`: Website name. Enter your site name. - `rate_limit`:Rate limiting configuration. - `window_seconds`:Time window ttt, default `60`. - `max_requests`:Maximum number of requests sss, default `30`. Maximum sss requests allowed within ttt seconds. - `get_rate_limit`:Independent rate limiting for GET requests. - `window_seconds`:Time window ttt, default `60`. - `max_requests`:Maximum number of requests sss, default `45`. Maximum sss GET requests (page loads, favicon, etc.) within ttt seconds. - `save_rate_limit`:Independent rate limiting for save-type POST requests (note saves / share write-backs). - `window_seconds`:Time window ttt, default `60`. - `max_requests`:Maximum number of requests sss, default `120`. Maximum sss note saves within ttt seconds, decoupled from the global POST limit (`rate_limit`) so frequent saves are not throttled. - `trust_proxy_headers`:Whether to trust `X-Forwarded-For` / `X-Real-IP` headers set by a reverse proxy, default `false`. **Security note**: Disabled by default — rate limiting is always based on the direct TCP peer IP to prevent clients from forging headers to bypass limits. Only set to `true` when deployed behind a trusted reverse proxy (e.g. Nginx). - `secure_cookies`:Whether to add the `Secure` flag to the session cookie, default `false`. **Security note**: Only set to `true` when the site is served over HTTPS; otherwise browsers will refuse to send the cookie over HTTP. - `id_generation`:Random URL generation configuration. - `length`:URL length, default `4`. - `use_uppercase`:Use uppercase letters, default `false`. - `use_lowercase`:Use lowercase letters, default `true`. - `use_digits`:Use digits, default `false`. - `share_token`:Share link token configuration. - `length`:Token length, default `64`. - `use_uppercase`:Use uppercase letters, default `true`. - `use_lowercase`:Use lowercase letters, default `true`. - `use_digits`:Use digits, default `true`. - `session_timeout`:Session timeout configuration. - `enabled`:Enable session timeout, default `false`. - `minutes`:Timeout duration (in **minutes**), default 151515. Visitors will be logged out when the session exceeds the configured time. - `note_expiration`:Note auto-cleanup (notes/clipboards are deleted after their save duration expires). - `enabled`:Enable auto-cleanup, default `false`. - `hours`:Save duration (in **hours**), default 242424. When enabled, notes (public + private) not modified within the configured hours are deleted by a background thread, which scans every 30 minutes. - `global_cdn`: Base URL of the global CDN for front-end static assets. - Default `https://cdn.jsdmirror.cn`. Front-end assets are loaded by concatenating this base URL: FontAwesome icons, the marked editor script, DOMPurify, and KaTeX (all use `npm/`\-style paths, so `https://cdn.jsdelivr.net` and other npm CDNs also work). You can replace the whole CDN in `config.json` to match your network environment without touching code. - `latex_render`: LaTeX formula rendering. - `enabled`: Enable rendering, default `true`. - KaTeX static assets are loaded from the `global_cdn` base URL (default jsdmirror; jsdelivr, etc. also work). When enabled, Markdown read-only pages support `$...$` inline and `$$...$$` display math (KaTeX, client-side rendering, no server dependency). - `code_highlight`: code highlighting (highlight.js, client-side rendering). - `enabled`: Enable highlighting, default `true`. - `cdn`: Base directory of highlight.js static files, default jsdelivr’s `@highlightjs/cdn-assets` package; China mirrors can use jsdmirror (e.g. `https://cdn.jsdmirror.cn/gh/highlightjs/cdn-release@11.9.0/build`). When enabled, code blocks in all Markdown-rendered locations (note read-only pages, editor live preview, benben feed, disclaimer) get automatic syntax highlighting with line numbers, following the site’s light/dark theme with no server dependency. - `avatar`: user avatars (generated via a third-party service, shown next to the current user in the navbar, benben post authors, and the user notes list title). - `enabled`: enable avatars, default `true`; set `false` to hide avatars entirely. - `url_template`: avatar URL template, default `https://cn.cravatar.com/avatar/{hash}?d=identicon&f=y`. Supports two placeholders: `{hash}` (`md5(username)` lowercase hex) and `{username}` (URL-encoded username). Since this site’s users have no email, `md5(username)` is used as the hash; `d=identicon` makes Gravatar-style services generate a deterministic geometric avatar per hash. You can also swap in other username-seeded services (e.g. DiceBear: `https://api.dicebear.com/9.x/identicon/svg?seed={username}`). - `size`: default size in the template (currently only a fallback value; templates use fixed sizes per location). - `password_policy`: password policy, defining the complexity requirements for guest passwords. - `min_length`: minimum password length, default `8`; - `max_length`: maximum password length, default `128` (hard cap `128`, preventing oversized passwords from entering the PBKDF2 slow hash and consuming CPU); - `require_uppercase`: whether uppercase letters are required, default `true`; - `require_lowercase`: whether lowercase letters are required, default `true`; - `require_digits`: whether digits are required, default `true`; - `require_special`: whether special characters (excluding `/ \ ( ) " '`) are required, default `true`; - `RUSIN_DATA_DIR`: optional environment variable for the runtime data directory, defaulting to the current project directory (`file` backend only). Notes, users, sessions, shares, and logs are written under this directory as `notes/`, `users.json`, `sessions.json`, `shares.json`, `benben.json`, and `log/`. On auto-deploy platforms such as Zeabur, mount a persistent volume at `/data` and set `RUSIN_DATA_DIR=/data` to prevent clipboard data from being cleared on each deployment. - `RUSIN_STORAGE`: optional env var to force the storage backend: `file` (default, local/VPS), `memory` (in-memory), `upstash` (external KV for serverless), `postgres` (Neon/PostgreSQL). When unset: `KV_REST_API_URL`/`KV_REST_API_TOKEN` set → `upstash`; `DATABASE_URL` set → `postgres`; serverless platform env detected → `memory`; otherwise `file`. See “Storage Backends” above. - **Multi-language**: The interface supports Simplified Chinese and English. Language switch links (`/lang/zh` / `/lang/en`) are provided on the right side of the navbar; the preference is remembered via a cookie (`rusin-lang`); when unset, it falls back to the browser’s `Accept-Language`, defaulting to Chinese. After switching, all site text (navbar, buttons, hints, error messages, benben previews, etc.) switches language instantly. - `benben` (feed at `/benben`, logged-in users can post, anonymous read-only). - `max_length`: max length of a single feed post (in **characters**), default `1024` (~1KB); - `page_size`: posts loaded per batch, default `50`; - `cooldown_seconds`: minimum interval between two posts by the same user (in **seconds**), default `3`; - `max_height_px`: maximum display height of rendered feed content (in **px**), default `1000`, overflow scrolls within the content area; - `max_posts`: maximum number of posts persisted, default `200` (keeps external KV value size bounded; oldest posts are dropped); Content supports Markdown and LaTeX math (`$...$` / `$$...$$`, controlled by the `latex_render` switch); the post form has a live preview (client-side marked.js rendering, which filters dangerous tags and links too); rendering is sanitized with bleach to prevent XSS; each page shows `page_size` posts, loaded in batches via “Load more”; loading and posting are both subject to request rate limits (GET/POST), and posting is also subject to a per-user cooldown (`cooldown_seconds`); each post’s header shows the poster’s IP (whether proxy headers are trusted follows `trust_proxy_headers`; not shown for old data without an IP field). --- ## 单源最短路算法 URL: https://blog.rusin7.com/en/article/shortest-path 本文将会单源最短路的定义,并给出 SPFA、Bellman-Ford、Dijkstra 等多种用于求单源最短路的算法并进行比较。 Sep 5, 2026 / Update Sep 29, 2026 11 分钟 zh [c++](/tags/c++) / [笔记](/tags/笔记) # 单源最短路算法 > 本文将会单源最短路的定义,并给出 SPFA、Bellman-Ford、Dijkstra 等多种用于求单源最短路的算法并进行比较。 views [| comments](#waline) ## 定义[#](#定义) **单源最短路**的定义:给定一个起点,求它到所有其他点的最短距离。 注 这里给出的定义较宽泛,没有提到边权的非负性。 在做题过程中,这点需要注意,并根据题面选择算法。 现在,来看看怎么解决此类问题。 模板题: [P3371 【模板】单源最短路径(弱化版) ↗](https://www.luogu.com.cn/problem/P3371) [P4779 【模板】单源最短路径(标准版) ↗](https://www.luogu.com.cn/problem/P4779) ## Dijkstra 算法[#](#dijkstra-算法) ### 算法思想[#](#算法思想) **前提**:所有边权非负。 Dijkstra 核心思想:贪心 + 逐步确定。 想象从起点 sss 出发,初始只知道到 sss 自己的距离是 000,到其他点都设为无穷大。然后不断做一件事: > 在**还没确定最短距离**的点中,选一个**当前距离最小**的点,这个距离就是它的最终最短距离。 反证法:如果这个距离不是它的最终最短距离,则必存在一条距离更短的路,但不可能通过其他未确定点再绕路到 uuu 得到更短距离,因为任何绕路都会先经过一个距离更大的点,再加上非负边权,只会更远。故假设不成立,结论成立。 所以我们可以把这个点“确定”下来,并用它去更新它的邻接点,直到所有点都被最终最短距离都被确定。 ### 算法步骤[#](#算法步骤) sss 表示源点。 初始化整个 disdisdis 为 INF,然后令 diss\=0dis\_s = 0diss​\=0。 遍历最多 nnn 次,每次确定一个点 uuu 的最终最短距离(松弛): - 在所有未确定的点中,找到 disudis\_udisu​ 最小的点 uuu。 - 将 uuu 标记为已确定,此时 disudis\_udisu​ **已经是** sss 到 uuu 的最短距离,后续不会再被更新。 - 如果没有任何未确定的点,则说明所有点最短距离已确定,可以 `break`。否则遍历 uuu 的所有出边 u→vu \\to vu→v,如果 disu+w using namespace std; const int N=10005,M=500005; int n,m,s,head[N],cnt,dis[N],vis[N]; struct edge{ int w,to,nxt; }e[M]; void add(int u,int v,int w){ e[++cnt].w=w; e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } void dij(int s){ for(int i=0;i>n>>m>>s; memset(head,-1,sizeof head); for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; add(u,v,w); } dij(s); for(int i=1;i<=n;++i){ if(dis[i]==0x3f3f3f3f)cout<<2147483647<<' '; else cout< #define pii pair using namespace std; const int N=100005,M=200005; int n,m,s,head[N],cnt,dis[N],vis[N]; struct edge{ int w,to,nxt; }e[M]; void add(int u,int v,int w){ e[++cnt].w=w; e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } priority_queue,greater >pq; void dij(int s){ for(int i=0;i>n>>m>>s; memset(head,-1,sizeof head); for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; add(u,v,w); } dij(s); for(int i=1;i<=n;++i){ if(dis[i]==0x3f3f3f3f)cout<<2147483647<<' '; else cout< using namespace std; const int N=2e3+5,M=3e3+5; int T,n,m,cnt,dis[N]; struct edge{ int u,v,w; }e[2*M]; void add(int u,int v,int w){ e[++cnt]={u,v,w}; } bool BellmanFord(){ bool f=0; for(int i=1;i<=n;++i){ bool upd=0; for(int j=1;j<=cnt;++j){ int u=e[j].u,v=e[j].v,w=e[j].w; if(dis[u]!=0x3f3f3f3f&&dis[u]+w>T; while(T--){ cin>>n>>m; cnt=0; for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; if(w>=0){ add(u,v,w); add(v,u,w); }else{ add(u,v,w); } } for(int i=0;i using namespace std; const int N=10005,M=500005; int n,m,s,head[N],cnt,dis[N],vis[N],inq[N]; struct edge{ int w,to,nxt; }e[M]; void add(int u,int v,int w){ e[++cnt].w=w; e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } queueq; void spfa(int s){ for(int i=0;i>n>>m>>s; memset(head,-1,sizeof head); for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; add(u,v,w); } spfa(s); for(int i=1;i<=n;++i){ if(dis[i]==0x3f3f3f3f)cout<<2147483647<<' '; else cout< using namespace std; const int N=2e3+5,M=3e3+5; int T,n,m,head[N],cnt,dis[N],inq[N],quecnt[N]; struct edge{ int w,to,nxt; }e[2*M]; void add(int u,int v,int w){ e[++cnt].w=w; e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } queueq; bool spfa(){ for(int i=0;i=n)return true; inq[v]=1; } } } } return false; } int main(){ cin>>T; while(T--){ cin>>n>>m; cnt=0; memset(head,-1,sizeof head); memset(inq,0,sizeof inq); memset(quecnt,0,sizeof quecnt); while(!q.empty())q.pop(); for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; if(w>=0){ add(u,v,w); add(v,u,w); }else{ add(u,v,w); } } cout<<(spfa()?"YES":"NO")<<'\n'; } return 0; } ``` cpp 更多算法待补充…… ## 对比[#](#对比) | 算法 | 能否处理负权边 | 是否判负环 | 时间复杂度 | 实现难度 | 稳定性 | | --- | --- | --- | --- | --- | --- | | Dijkstra(朴素) | 不能 | 不能 | O(n2+m)O(n² + m)O(n2+m) | 简单 | 稳定 | | Dijkstra(堆优化) | 不能 | 不能 | O((n+m)logm)O((n+m) log m)O((n+m)logm) | 中等 | 稳定 | | Bellman-Ford | 能 | 能 | O(nm)O(nm)O(nm) | 较简单 | 稳定 | | SPFA | 能 | 能 | 平均 O(km)O(km)O(km),最坏 O(nm)O(nm)O(nm) | 中等 | 不稳定(可被卡) | ## 结语[#](#结语) 在 [NOI 大纲 2025 修订版 ↗](https://www.noi.cn/upload/resources/file/2025/04/18/NOI_Syllabus_Edition_2025.pdf) 中,单源最短路位于提高组 2.2.42.2.42.2.4 中的 7.图论算法中的第【6】项,是图论中较为基础的算法。学会它,也可以为以后更多更复杂的图论算法打下坚实的基础。 --- ## Solution URL: https://blog.rusin7.com/en/article/solution Posts in category: Solution # Solution [](/en/article/ccf "Previous: CSP NOIP NOI")[](/en/article/tech "Next: Technical") Page 1 - Showing 9 of 9 posts [View all posts by years →](/en/archives) - [![题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ! 本文讲述了如何使用 C++ 完成洛谷的 AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!,思路清晰、排版精美 4 分钟](/en/article/at-pakencamp-2020-day1-d-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P13361 \[GCJ 2011 Qualification\] Bot Trust](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 题解:P13361 \[GCJ 2011 Qualification\] Bot Trust 本文讲述了如何使用 C++ 完成洛谷的 P13361 \[GCJ 2011 Qualification\] Bot Trust」水落溪流浅浅,思路清晰、排版精美 4 分钟](/en/article/p13361-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P8506 标题计数](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 题解:P8506 标题计数 本文讲述了如何使用 C++ 完成洛谷的 P8506 标题计数,思路清晰、排版精美 3 分钟](/en/article/p8506-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P8534 「Wdoi-2」比赤色更红的梦](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 题解:P8534 「Wdoi-2」比赤色更红的梦 本文讲述了如何使用 C++ 完成洛谷的 P8534 「Wdoi-2」比赤色更红的梦,思路清晰、排版精美 2 分钟](/en/article/p8534-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P14702 \[ICPC 2024 Tehran R\] Boat](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Apr 3, 2026 题解:P14702 \[ICPC 2024 Tehran R\] Boat 本文讲述了如何使用 C++ 完成洛谷的 题解:P14702 \[ICPC 2024 Tehran R\] Boat,思路清晰、排版精美 2 分钟](/en/article/p14702-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Apr 3, 2026 题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree 本文讲述了如何使用 C++ 完成洛谷的 P14731 \[ICPC 2022 Seoul R\] Parentheses Tree,思路清晰、排版精美 2 分钟](/en/article/p14731-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:AT\_joi2024\_yo1c\_b 桁 (Digit)](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 30, 2026 题解:AT\_joi2024\_yo1c\_b 桁 (Digit) 本文讲述了如何使用 C++ 完成洛谷的 AT\_joi2024\_yo1c\_b 桁 (Digit),思路清晰、排版精美 1 分钟](/en/article/at-joi2024) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 30, 2026 题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type 本文讲述了如何使用 C++ 完成洛谷的 P14730 \[ICPC 2022 Seoul R\] Palindrome Type,思路清晰、排版精美 2 分钟](/en/article/p14730-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:CF2139B Cake Collection](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 23, 2026 题解:CF2139B Cake Collection 本文讲述了如何使用 C++ 完成洛谷的 CF2139B Cake Collection,思路清晰、排版精美 3 分钟](/en/article/cf2139b-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) --- ## Technical URL: https://blog.rusin7.com/en/article/tech Posts in category: Technical # Technical [](/en/article/solution "Previous: Solution")[](/en/article/life "Next: Daily Life") Page 1 - Showing 13 of 13 posts [View all posts by years →](/en/archives) - [Aug 31, 2026 Cyanwind theme markdown syntax Learn the basic syntax of Markdown from beginner to advanced. 10 分钟 en ](/en/article/how-to-use-markdown) - [ tutorial ](/en/tags/tutorial) - [ markdown ](/en/tags/markdown) - [Jan 11, 2026 MDX Components: User & Advanced How to use built-in content components (Aside/Tabs, etc.) and advanced widgets (LinkPreview/GithubCard, etc.). 1 分钟 en ](/en/article/mdx-components) - [ markdown ](/en/tags/markdown) - [Jan 11, 2026 Writing Guide: Markdown / MDX Supported Markdown extensions, KaTeX math, Shiki code features, and when to use MDX. 1 分钟 en ](/en/article/writing-markdown-mdx) - [ markdown ](/en/tags/markdown) - [![Rusin note Project Recommend](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) Aug 13, 2026 Rusin note Project Recommend Recommend a lightweight Python project for server deployment. Welcome to submit PRs and join the development! 11 分钟 en](/en/article/rusin-note) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ 开源项目 ](/en/tags/开源项目) - [ 教程 ](/en/tags/教程) - [![在 VPS 上部署洛谷保存站](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) Aug 11, 2026 在 VPS 上部署洛谷保存站 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) 8 分钟](/en/article/deploy-lg-saver) - [ 云服务器 ](/en/tags/云服务器) - [ 建站 ](/en/tags/建站) - [ 教程 ](/en/tags/教程) - [Jun 7, 2026 在 Hexo 中复现洛谷插件 前言OIer都知道,洛谷中有个,非常好用,效果如下:succ 13 分钟 ](/en/article/luogu-plugin-in-hexo) - [ hexo ](/en/tags/hexo) - [ 安知鱼美化 ](/en/tags/安知鱼美化) - [May 14, 2026 拯救谷歌和 Github!你的新“自行车” 快速安装,找到最新版本,安装包选择方式:Windows:De 1 分钟 ](/en/article/devsidecar) - [ git ](/en/tags/git) - [May 12, 2026 Vercel 仅部署指定分支的方法 如何指定特殊分支? 从中选择的项目,在侧边栏中打开Settings 3 分钟 ](/en/article/vercel-deploying-only-1-branch) - [ git ](/en/tags/git) - [Apr 20, 2026 对单一仓库配置小号以远程管理小号仓库 命令行操作给这个仓库单独设置小号仅本地生效把远程地址绑定到小 1 分钟 ](/en/article/configure-a-single-warehouse) - [ vs code ]() - [ git ](/en/tags/git) - [Apr 19, 2026 在 VS code 上远程管理 Github 仓库并自动化部署项目 如果GitHub远程是没有提交的空仓库然后再绑定哦。 7 分钟 ](/en/article/remote-github-repo-on-vs-code) - [ vs code ]() - [ git ](/en/tags/git) - [ nodejs ](/en/tags/nodejs) - [![侧边栏添加个性定位欢迎信息](https://image.rusin7.com/file/hexo/cover/z7qOAkod.webp) Apr 6, 2026 侧边栏添加个性定位欢迎信息 前景介绍使用方法创建JS文件 9 分钟](/en/article/location-welcome-information) - [ hexo ](/en/tags/hexo) - [ 安知鱼美化 ](/en/tags/安知鱼美化) - [ 建站 ](/en/tags/建站) - [![在 arm64 中安装虚拟环境](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) Apr 3, 2026 在 arm64 中安装虚拟环境 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 3 分钟](/en/article/arm64-install-base) - [ git ](/en/tags/git) - [ nodejs ](/en/tags/nodejs) - [ 教程 ](/en/tags/教程) - [Mar 23, 2026 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/en/article/free-domain) - [ 白嫖 ](/en/tags/白嫖) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ cloudflare ](/en/tags/cloudflare) - [ 教程 ](/en/tags/教程) --- ## 网络流笔记 URL: https://blog.rusin7.com/en/article/the-network-flow-notes 增广路ek模板Dinic模板,网络流的定义 Jun 6, 2026 15 分钟 [笔记](/tags/笔记) / [c++](/tags/c++) # 网络流笔记 > 增广路ek模板Dinic模板,网络流的定义 views [| comments](#waline) ## 增广路[#](#增广路) ek 模板: ``` #include using ll=long long; using namespace std; const int N=205,M=5005; int n,m,s,t,cnt=1,head[N],pre[N],mf[N]; /* mf:当前增广路可通过水流 */ struct edge{ int nxt,to,w; }e[2*M]; void add(int u,int v,int w){ e[++cnt].w=w; e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } bool bfs(){ memset(mf,0,sizeof mf); queueq; q.push(s); mf[s]=1e9; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; if(mf[v]==0&&e[i].w){ mf[v]=min(mf[u],e[i].w); pre[v]=i; q.push(v); if(v==t)return 1; } } } return 0; } ll ek(){ ll fl=0; while(bfs()){ int v=t; while(v!=s){ int i=pre[v]; e[i].w-=mf[t]; e[i^1].w+=mf[t]; v=e[i^1].to; } fl+=mf[t]; } return fl; } int main(){ cin>>n>>m>>s>>t; for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; add(u,v,w); add(v,u,0); } cout< #define ll long long using namespace std; const int M=5005; int n,m,s,t,head[M],tot=1,d[M],cur[M]; struct edge{ int v,nxt; ll flow; }e[2*M]; void add(int u,int v,int w){ e[++tot]={v,head[u],w},head[u]=tot; } bool bfs(){ memset(d,0,sizeof d); memcpy(cur,head,sizeof head); queueq; q.push(s); d[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];~i;i=e[i].nxt){ int v=e[i].v; if(!d[v]&&e[i].flow){ d[v]=d[u]+1; if(v==t)return true; q.push(v); } } } return false; } ll dfs(int u,ll flow){ if(u==t||!flow)return flow; ll rest=flow; for(int &i=cur[u];~i;i=e[i].nxt){ int v=e[i].v; if(d[v]==d[u]+1&&e[i].flow){ ll k=dfs(v,min(rest,e[i].flow)); if(!k)d[v]=0; e[i].flow-=k,e[i^1].flow+=k; if(!(rest-=k))break; } } return flow-rest; } ll dinic(){ ll maxflow=0; while(bfs())maxflow+=dfs(s,INT_MAX); return maxflow; } int main(){ memset(head, -1, sizeof(head)); cin>>n>>m>>s>>t; for(int i=1;i<=m;++i){ int u,v,w; cin>>u>>v>>w; add(u,v,w),add(v,u,0); } cout<0c(u,v)-f(u,v) > 0c(u,v)−f(u,v)\>0,意味着残量网络中有一条从 uuu 到 vvv 的边。由于 u∈Su\\in Su∈S(从 sss 可达),那么 vvv 也可达,从而 v∈Sv\\in Sv∈S,与 v∈Tv\\in Tv∈T 矛盾。因此 f(u,v)\=c(u,v)f(u,v)=c(u,v)f(u,v)\=c(u,v)。 **接着证明** ∀ u∈T\\forall\\,u\\in T∀u∈T,v∈Sv\\in Sv∈S,原边 (u,v)(u,v)(u,v) 必然无流量。 还是反证法。若存在 u∈Tu\\in Tu∈T,v∈Sv\\in Sv∈S 使得 f(u,v)\>0f(u,v) > 0f(u,v)\>0,则反向残量 f(u,v)\>0f(u,v) > 0f(u,v)\>0,意味着残量网络中有一条从 vvv 到 uuu 的边。由于 v∈Sv\\in Sv∈S(从 sss 可达),那么 uuu 也可达,从而 u∈Su\\in Su∈S,与 u∈Tu\\in Tu∈T 矛盾。因此 f(u,v)\=0f(u,v)=0f(u,v)\=0。 **最后计算** ∣f∣\\left\\lvert f\\right\\rvert∣f∣。 由弱对偶性证明中的等式: ∣f∣\=∑u∈S, v∈Tf(u,v)−∑v∈T, u∈Sf(v,u)\\left\\lvert f\\right\\rvert = \\sum\_{u\\in S,\\,v\\in T} f(u,v) - \\sum\_{v\\in T,\\,u\\in S} f(v,u)∣f∣\=∑u∈S,v∈T​f(u,v)−∑v∈T,u∈S​f(v,u) 由“再证明”的结论,第一项中 f(u,v)\=c(u,v)f(u,v)=c(u,v)f(u,v)\=c(u,v);由“接着证明”的结论,第二项中 f(v,u)\=0f(v,u)=0f(v,u)\=0。因此: ∣f∣\=∑u∈S, v∈Tc(u,v)\=c(S,T)\\left\\lvert f\\right\\rvert = \\sum\_{u\\in S,\\,v\\in T} c(u,v) = c(S,T)∣f∣\=∑u∈S,v∈T​c(u,v)\=c(S,T) 这就找到了一个割,其容量等于 ∣f∣\\left\\lvert f\\right\\rvert∣f∣。证毕! 综上,证毕! ## Part. 4 增广路定理[#](#part-4-增广路定理) 定理:一个可行流 fff 是最大流当且仅当残量网络 GfG\_fGf​ 中不存在 sss 到 ttt 的路径(称为增广路)。 证明 (⇒\\Rightarrow⇒)若存在增广路 PPP,设 δ\=min⁡{r(u,v):(u,v)∈P}\>0\\delta = \\min\\{r(u,v): (u,v)\\in P\\} > 0δ\=min{r(u,v):(u,v)∈P}\>0。沿 PPP 增加 δ\\deltaδ 流量: - 对正向残量边:f(u,v)←f(u,v)+δf(u,v) \\leftarrow f(u,v) + \\deltaf(u,v)←f(u,v)+δ - 对反向残量边:f(v,u)←f(v,u)−δf(v,u) \\leftarrow f(v,u) - \\deltaf(v,u)←f(v,u)−δ 得到的新流仍满足容量约束,且 ∣f′∣\=∣f∣+δ\>∣f∣|f'| = \\left\\lvert f\\right\\rvert + \\delta > \\left\\lvert f\\right\\rvert∣f′∣\=∣f∣+δ\>∣f∣,故 fff 不是最大流。逆否命题成立。 (⇐\\Leftarrow⇐)若无增广路,定义 SSS 为 sss 在 GfG\_fGf​ 中可达的节点集,则 t∉St\\notin St∈/S。由 Part.3 “再证明”的证明过程,∣f∣\=c(S,T)\\left\\lvert f\\right\\rvert = c(S,T)∣f∣\=c(S,T),再由弱对偶性知 fff 是最大流。证毕! ## Part.5 Dinic 算法的分层图引理[#](#part5-dinic-算法的分层图引理) 定义:在残量网络中,定义 d(u)d(u)d(u) 为从 sss 到 uuu 的最短边数(BFS 距离)。边 (u,v)(u,v)(u,v) 称为允许边若 d(v)\=d(u)+1d(v) = d(u) + 1d(v)\=d(u)+1 且残量 \>0\>0\>0。所有允许边构成分层图 LfL\_fLf​。阻塞流是指在 LfL\_fLf​ 中无法再找到增广路的流。 引理:记 dk(t)d\_k(t)dk​(t) 为第 kkk 次阻塞流增广后 ttt 的距离。则 dk+1(t)\>dk(t)d\_{k+1}(t) > d\_k(t)dk+1​(t)\>dk​(t)。 证明 设 fff 是当前流,f′f'f′ 是增广一次阻塞流后得到的新流。考虑 Gf′G\_{f'}Gf′​ 中 sss 到 ttt 的最短路径 PPP。若 PPP 中存在一条边 (u,v)(u,v)(u,v) 在 GfG\_fGf​ 中不存在(即由增广操作新产生的反向边),则 f(v,u)\>0f(v,u) > 0f(v,u)\>0,这意味着在 GfG\_fGf​ 中 uuu 到 vvv 有容量 \>0\>0\>0 的边。由 PPP 的最短性可推出矛盾。因此 PPP 中的所有边都在 GfG\_fGf​ 中存在,但阻塞流增广后,至少有一条 GfG\_fGf​ 中的最短路径上的边被饱和,故 PPP 的长度必然大于 dk(t)d\_k(t)dk​(t)。证毕! 推论:Dinic 算法中 BFS 的次数不超过 ∣V∣\\lvert V\\rvert∣V∣,故总复杂度 O(∣V∣2∣E∣)O(\\lvert V\\rvert^2\\lvert E\\rvert)O(∣V∣2∣E∣)。 ## Part.6 Dinic 算法实践[#](#part6-dinic-算法实践) ### 当前弧优化[#](#当前弧优化) 代码中的 `cur[]` 实现了当前弧优化。其原理是:在 DFS 过程中,若某条边已被尝试且无法推送更多流量,则同一轮 BFS 分层中无需再次尝试,直接从下一条边开始。 ### 代码[#](#代码) ``` struct Edge { int to, weight, nxt; } edges[MAXM << 1]; int head[MAXN], ecnt = 2, n, m; void addedge(int u, int v, int weight) { edges[ecnt] = Edge{v, weight, head[u]}; head[u] = ecnt++; } int dep[MAXN], cur[MAXN], s, t; bool bfs() { clean(dep); queue < int > q; dep[s] = 1; q.psh(s); while (q.size()) { int u = q.front(); q.pop(); for (int i = head[u]; i; i = edges[i].nxt) { int v = edges[i].to; if (!dep[v] && edges[i].weight) { dep[v] = dep[u] + 1; q.psh(v); if (v == t) return true; } } } return false; } int dfs(int u, int flow) { if (u == t) return flow; int used = 0; for (int &i = cur[u]; i; i = edges[i].nxt) { int v = edges[i].to; if (dep[v] == dep[u] + 1 && edges[i].weight) { int res = dfs(v, min(flow - used, edges[i].weight)); if (res) { edges[i].weight -= res; edges[i ^ 1].weight += res; used += res; } if (used == flow) break; } } return used; } int dinic() { int mf = 0; while (bfs()) { memcpy(cur, head, sizeof cur); while (int res = dfs(s, inf)) mf += res; } return mf; } ``` cpp ## Part.7 HLPP(最高标号预流推进)算法[#](#part7-hlpp最高标号预流推进算法) ### 7.1 算法思想和基本概念[#](#71-算法思想和基本概念) HLPP(Highest-Label Preflow Push)与 Dinic 等增广路算法不同,采用预流推进的思路: 1. 不保持流量守恒:允许节点暂时存储超额流。 2. 高度函数:给每个节点一个高度,流只能从高处向低处推送。 3. 最高标号优先:每次选择高度最高的活跃节点处理。 定义超额流 e(u)e(u)e(u): e(u)\=∑vf(v,u)−∑vf(u,v)e(u) = \\sum\_{v} f(v,u) - \\sum\_{v} f(u,v)e(u)\=∑v​f(v,u)−∑v​f(u,v) - 当 e(u)\>0e(u) > 0e(u)\>0 时,uuu 称为**活跃节点** - 源点 sss 和汇点 ttt 除外 定义高度函数 h(u)h(u)h(u): - 流只能从高向低推:h(u)\=h(v)+1h(u) = h(v) + 1h(u)\=h(v)+1 - 初始高度:从 ttt 反向 BFS 得到,h(t)\=0h(t)=0h(t)\=0,h(s)\=nh(s)=nh(s)\=n ### 7.2 核心操作[#](#72-核心操作) 推流:当 e(u)\>0e(u) > 0e(u)\>0 且存在边 (u,v)(u,v)(u,v) 满足 r(u,v)\>0r(u,v) > 0r(u,v)\>0 且 h(u)\=h(v)+1h(u) = h(v) + 1h(u)\=h(v)+1 时,推送流量: δ\=min⁡(e(u),r(u,v))\\delta = \\min(e(u), r(u,v))δ\=min(e(u),r(u,v)) 重贴标签:当 e(u)\>0e(u) > 0e(u)\>0 但无可推流的邻居时,更新高度: h(u)\=min⁡{h(v)+1∣r(u,v)\>0}h(u) = \\min\\{h(v) + 1 \\mid r(u,v) > 0\\}h(u)\=min{h(v)+1∣r(u,v)\>0} ### 7.4 核心优化[#](#74-核心优化) - 最高标号优先:使用优先队列或桶维护活跃节点,每次取高度最大的处理。 - GAP 优化:若某个高度 kkk 的节点数为 0,则所有高度 \>k\>k\>k 的节点无法到达 ttt,直接将其高度设为 n+1n+1n+1。 - 当前弧优化:与 Dinic 相同,避免重复遍历已饱和的边。 ### 7.5 算法流程[#](#75-算法流程) ``` HLPP(s, t): 1. 反向 BFS 初始化高度 h,h[s] = n 2. 从 s 饱和推流,将活跃节点入桶 3. while mxh >= 0: u = 桶中最高高度的节点 for 当前弧遍历出边: if 边有残量 and h[u] == h[v] + 1: push(u, v) if e[u] == 0: break if e[u] > 0: relabel(u) 4. return e[t] ``` cpp ### 7.6 代码实现[#](#76-代码实现) ``` struct Edge { int to, nxt, cap; } edges[MAXM]; int head[MAXN], ecnt = 2, n, m; void addedge(int u, int v, int cap) { edges[ecnt] = {v, head[u], cap}, head[u] = ecnt++; edges[ecnt] = {u, head[v], 0}, head[v] = ecnt++; } int h[MAXN], eflow[MAXN], cur[MAXN], gap[MAXN << 1], mxh, s, t; vi bucket[MAXN << 1]; bool inq[MAXN]; void bfs() { memset(h, 0x3f, sizeof h); static int q[MAXN], qh, qt; h[t] = 0, q[qt = 0] = t, qh = 0, ++qt; while (qh < qt) { int u = q[qh++]; for (int i = head[u]; i; i = edges[i].nxt) { int v = edges[i].to; if (edges[i ^ 1].cap && h[v] > h[u] + 1) h[v] = h[u] + 1, q[qt++] = v; } } h[s] = n; } void push(int u) { for (int &i = cur[u]; i; i = edges[i].nxt) { int v = edges[i].to; if (edges[i].cap && h[u] == h[v] + 1) { int delta = min(eflow[u], edges[i].cap); if (!delta) continue; edges[i].cap -= delta, edges[i ^ 1].cap += delta; eflow[u] -= delta, eflow[v] += delta; if (v != s && v != t && !inq[v] && eflow[v]) inq[v] = true, bucket[h[v]].pb(v), mxh = max(mxh, h[v]); if (!eflow[u]) break; } } } void relabel(int u) { int mnh = inf; for (int i = head[u]; i; i = edges[i].nxt) if (edges[i].cap) mnh = min(mnh, h[edges[i].to]); int nwh = mnh + 1; if (!(--gap[h[u]]) && h[u] < n) { up(i, 1, n) if (i != s && i != t && h[i] > h[u] && h[i] <= n) h[i] = n + 1; up(i, h[u] + 1, n) { for (int v : bucket[i]) inq[v] = false; bucket[i].clear(); gap[n] += gap[i], gap[i] = 0; } } h[u] = nwh; if (nwh <= n) ++gap[nwh], bucket[nwh].pb(u), inq[u] = true, mxh = max(mxh, nwh); cur[u] = head[u]; } int hlpp() { if (s == t) return 0; bfs(); clean(gap), clean(eflow), clean(inq); up(i, 1, n) { if (h[i] < n) ++gap[h[i]]; else ++gap[n]; } for (int i = head[s]; i; i = edges[i].nxt) { int v = edges[i].to, cap = edges[i].cap; if (cap) { edges[i].cap -= cap, edges[i ^ 1].cap += cap; eflow[s] -= cap, eflow[v] += cap; if (v != t && eflow[v] && !inq[v] && h[v] < n) inq[v] = true, bucket[h[v]].pb(v), mxh = max(mxh, h[v]); } } while (mxh >= 0) { while (mxh >= 0 && bucket[mxh].empty()) --mxh; if (mxh < 0) break; int u = bucket[mxh].back(); bucket[mxh].ppb(); inq[u] = false; if (!eflow[u]) continue; if (!cur[u]) cur[u] = head[u]; push(u); if (eflow[u]) relabel(u); } return eflow[t]; } ``` cpp ## Part.8 题目选讲 A[#](#part8-题目选讲-a) ### [P3376 【模板】网络最大流 ↗](https://www.luogu.com.cn/problem/P3376) & [P4722 【模板】最大流 加强版 / 预流推进 ↗](https://www.luogu.com.cn/problem/P4722)[#](#p3376-模板网络最大流--p4722-模板最大流-加强版--预流推进) 模板题,代码见上。 ### [P2740 \[USACO4.2\] 草地排水 Drainage Ditches ↗](https://www.luogu.com.cn/problem/P2740)[#](#p2740-usaco42-草地排水-drainage-ditches) s\=1, t\=ns=1,\\ t=ns\=1, t\=n ### [P2936 \[USACO09JAN\] Total Flow S ↗](https://www.luogu.com.cn/problem/P2936)[#](#p2936-usaco09jan-total-flow-s) 换成字符。 ### [P1343 地震逃生 ↗](https://www.luogu.com.cn/problem/P1343)[#](#p1343-地震逃生) ans\=0ans=0ans\=0 特判。 ### [P3386 【模板】二分图最大匹配 ↗](https://www.luogu.com.cn/problem/P3386)[#](#p3386-模板二分图最大匹配) 构造: - 虚拟一个 sss,与左部所有点建边。 - 左右部建边。 - 虚拟一个 ttt,与右部所有点建边。 如图: ![1](https://cdn.luogu.com.cn/upload/image_hosting/u9ov9vcs.png) --- ## Vercel 仅部署指定分支的方法 URL: https://blog.rusin7.com/en/article/vercel-deploying-only-1-branch 如何指定特殊分支? 从中选择的项目,在侧边栏中打开Settings May 12, 2026 3 分钟 [git](/tags/git) # Vercel 仅部署指定分支的方法 > 如何指定特殊分支? 从中选择的项目,在侧边栏中打开Settings views [| comments](#waline) ## 如何指定特殊分支[#](#如何指定特殊分支) 1. 从[仪表板 ↗](https://vercel.com/dashboard)中选择的项目 2. 在侧边栏中打开 Settings。 3. 点击 Environments。 4. 点击 Production 环境(/settings/environments/production)。 {% tip cogs %}这样配置之后,Vercel 仍然会在任一分支更改时自动构建,结果当然是 {% label Error red %} 了!怎么办呢?{% endtip %} ## 使用分支跟踪(推荐)[#](#使用分支跟踪推荐) 最直接的方法是在项目设置中配置分支跟踪。默认情况下,Vercel 会在所有分支上触发部署,但可以指定 {% label main red %} red %} 分支作为生产环境分支,这样只有 {% label main red %} 分支的变更才会触发生产部署。 开启分支跟踪非常简单,按照以下步骤操作: 1. 从[仪表板 ↗](https://vercel.com/dashboard)中选择的项目 2. 在侧边栏中打开 Settings。 3. 点击 Environments。 4. 点击 Production 环境(/settings/environments/production)。 5. 在 Branch Tracking 中,输入想要追踪的分支名称,例如 {% label main red %}。 6. 点击 `Save`。 还可以在 Preview 环境(/settings/environments/preview)中关闭 Branch Tracking。这样就可以确保只有 {% label main red %} 分支的变更才会触发任何构建。 ## 使用 git 配置[#](#使用-git-配置) 在项目根目录的 `vercel.json` 文件中添加 `git.deploymentEnabled` 配置,精确控制哪些分支可以触发部署: ``` { "git": { "deploymentEnabled": { "main": true } } } ``` json ## 使用忽略构建步骤[#](#使用忽略构建步骤) 如果需要更灵活的控制,可以在项目设置的“忽略构建步骤”部分使用自定义 Bash 脚本: ``` #!/bin/bash if [[ "$VERCEL_GIT_COMMIT_REF" == "main" ]]; then exit 1 # 继续构建 else exit 0 # 跳过构建 fi ``` bash --- ## Writing Guide: Markdown / MDX URL: https://blog.rusin7.com/en/article/writing-markdown-mdx Supported Markdown extensions, KaTeX math, Shiki code features, and when to use MDX. Jan 11, 2026 / Update Jan 11, 2026 1 分钟 en [markdown](/tags/markdown) # Writing Guide: Markdown / MDX > Supported Markdown extensions, KaTeX math, Shiki code features, and when to use MDX. views [| comments](#waline) ## 1\. Markdown Features[#](#1-markdown-features) Enabled by default: - GFM: tables, strikethrough, task lists - Math: KaTeX (`$...$` / `$$...$$`) - Code highlighting: Shiki (titles, diff/highlight notations) ## 2\. Math (KaTeX)[#](#2-math-katex) Inline: ``` Euler: $e^{i\\pi}+1=0$ ``` md Block: ``` $$ \\int_0^1 x^2 dx = \\frac{1}{3} $$ ``` md ## 3\. Code Notations (diff / highlight)[#](#3-code-notations-diff--highlight) Diff-like markers (powered by the theme’s Shiki transformers): ``` const a = 1 const a = 2 ``` ts Highlight: ``` const token = 'secret' ``` ts ## 4\. When to Use MDX[#](#4-when-to-use-mdx) Use `.mdx` when you want to import and render components inside content (e.g. `Aside`, `Tabs`, `GithubCard`). See the “MDX Components” doc for examples. --- ## Astro-theme-cyanwind Documentation URL: https://blog.rusin7.com/en/collection/docs Bilingual docs for setup, deployment, and writing. ![Astro-theme-cyanwind Documentation](https://picr2.axi404.top/1767811093734_image.webp) # Astro-theme-cyanwind Documentation Bilingual docs for setup, deployment, and writing. - [Jan 11, 2026 Writing Guide: Markdown / MDX Supported Markdown extensions, KaTeX math, Shiki code features, and when to use MDX. 1 分钟 en ](/en/article/writing-markdown-mdx) - [ markdown ](/en/tags/markdown) - [Jan 11, 2026 MDX Components: User & Advanced How to use built-in content components (Aside/Tabs, etc.) and advanced widgets (LinkPreview/GithubCard, etc.). 1 分钟 en ](/en/article/mdx-components) - [ markdown ](/en/tags/markdown) --- ## Tags: #c++ URL: https://blog.rusin7.com/en/tags/c++ View all posts with the tag - c++ # Tags: #c++ - [Sep 29, 2026 ## 单源最短路算法 本文将会单源最短路的定义,并给出 SPFA、Bellman-Ford、Dijkstra 等多种用于求单源最短路的算法并进行比较。 11 分钟 zh ](/en/article/shortest-path) - [ c++ ](/en/tags/c++) - [ 笔记 ](/en/tags/笔记) - [Jul 22, 2026 ## 洛谷网校 CSP 初赛笔记 笔记 2 分钟 ](/en/article/luogu-class-csp-j-note) - [ c++ ](/en/tags/c++) - [Jun 7, 2026 ## 笔记——树形动态规划 若如图所示,当前dfs至点u,则转移方程得 2 分钟 ](/en/article/notes-of-dp-on-trees) - [ 笔记 ](/en/tags/笔记) - [ c++ ](/en/tags/c++) - [![题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 ## 题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ! 本文讲述了如何使用 C++ 完成洛谷的 AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!,思路清晰、排版精美 4 分钟](/en/article/at-pakencamp-2020-day1-d-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [Jun 6, 2026 ## AC 自动机笔记 AC 自动机笔记 1 分钟 ](/en/article/automated-ac) - [ 笔记 ](/en/tags/笔记) - [ c++ ](/en/tags/c++) - [![题解:P13361 \[GCJ 2011 Qualification\] Bot Trust](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 ## 题解:P13361 \[GCJ 2011 Qualification\] Bot Trust 本文讲述了如何使用 C++ 完成洛谷的 P13361 \[GCJ 2011 Qualification\] Bot Trust」水落溪流浅浅,思路清晰、排版精美 4 分钟](/en/article/p13361-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P8506 标题计数](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 ## 题解:P8506 标题计数 本文讲述了如何使用 C++ 完成洛谷的 P8506 标题计数,思路清晰、排版精美 3 分钟](/en/article/p8506-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P8534 「Wdoi-2」比赤色更红的梦](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 ## 题解:P8534 「Wdoi-2」比赤色更红的梦 本文讲述了如何使用 C++ 完成洛谷的 P8534 「Wdoi-2」比赤色更红的梦,思路清晰、排版精美 2 分钟](/en/article/p8534-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [Jun 6, 2026 ## 网络流笔记 增广路ek模板Dinic模板,网络流的定义 15 分钟 ](/en/article/the-network-flow-notes) - [ 笔记 ](/en/tags/笔记) - [ c++ ](/en/tags/c++) - [![图论之欧拉回路、差分约束——算法笔记](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Apr 3, 2026 ## 图论之欧拉回路、差分约束——算法笔记 本文讲述了图论之欧拉回路、差分约束的 C++ 代码,并推荐了比赛和题目以便练习。 2 分钟](/en/article/euro-circuit-notes) - [ c++ ](/en/tags/c++) - [![题解:P14702 \[ICPC 2024 Tehran R\] Boat](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Apr 3, 2026 ## 题解:P14702 \[ICPC 2024 Tehran R\] Boat 本文讲述了如何使用 C++ 完成洛谷的 题解:P14702 \[ICPC 2024 Tehran R\] Boat,思路清晰、排版精美 2 分钟](/en/article/p14702-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Apr 3, 2026 ## 题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree 本文讲述了如何使用 C++ 完成洛谷的 P14731 \[ICPC 2022 Seoul R\] Parentheses Tree,思路清晰、排版精美 2 分钟](/en/article/p14731-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:AT\_joi2024\_yo1c\_b 桁 (Digit)](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 30, 2026 ## 题解:AT\_joi2024\_yo1c\_b 桁 (Digit) 本文讲述了如何使用 C++ 完成洛谷的 AT\_joi2024\_yo1c\_b 桁 (Digit),思路清晰、排版精美 1 分钟](/en/article/at-joi2024) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 30, 2026 ## 题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type 本文讲述了如何使用 C++ 完成洛谷的 P14730 \[ICPC 2022 Seoul R\] Palindrome Type,思路清晰、排版精美 2 分钟](/en/article/p14730-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:CF2139B Cake Collection](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 23, 2026 ## 题解:CF2139B Cake Collection 本文讲述了如何使用 C++ 完成洛谷的 CF2139B Cake Collection,思路清晰、排版精美 3 分钟](/en/article/cf2139b-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) --- ## Tags: #cloudflare URL: https://blog.rusin7.com/en/tags/cloudflare View all posts with the tag - cloudflare # Tags: #cloudflare - [Mar 23, 2026 ## 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/en/article/free-domain) - [ 白嫖 ](/en/tags/白嫖) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ cloudflare ](/en/tags/cloudflare) - [ 教程 ](/en/tags/教程) --- ## Tags: #git URL: https://blog.rusin7.com/en/tags/git View all posts with the tag - git # Tags: #git - [May 14, 2026 ## 拯救谷歌和 Github!你的新“自行车” 快速安装,找到最新版本,安装包选择方式:Windows:De 1 分钟 ](/en/article/devsidecar) - [ git ](/en/tags/git) - [May 12, 2026 ## Vercel 仅部署指定分支的方法 如何指定特殊分支? 从中选择的项目,在侧边栏中打开Settings 3 分钟 ](/en/article/vercel-deploying-only-1-branch) - [ git ](/en/tags/git) - [Apr 20, 2026 ## 对单一仓库配置小号以远程管理小号仓库 命令行操作给这个仓库单独设置小号仅本地生效把远程地址绑定到小 1 分钟 ](/en/article/configure-a-single-warehouse) - [ vs code ]() - [ git ](/en/tags/git) - [Apr 19, 2026 ## 在 VS code 上远程管理 Github 仓库并自动化部署项目 如果GitHub远程是没有提交的空仓库然后再绑定哦。 7 分钟 ](/en/article/remote-github-repo-on-vs-code) - [ vs code ]() - [ git ](/en/tags/git) - [ nodejs ](/en/tags/nodejs) - [![在 arm64 中安装虚拟环境](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) Apr 3, 2026 ## 在 arm64 中安装虚拟环境 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 3 分钟](/en/article/arm64-install-base) - [ git ](/en/tags/git) - [ nodejs ](/en/tags/nodejs) - [ 教程 ](/en/tags/教程) --- ## Tags: #github URL: https://blog.rusin7.com/en/tags/github View all posts with the tag - github # Tags: #github - [![Rusin note Project Recommend](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) Aug 13, 2026 ## Rusin note Project Recommend Recommend a lightweight Python project for server deployment. Welcome to submit PRs and join the development! 11 分钟 en](/en/article/rusin-note) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ 开源项目 ](/en/tags/开源项目) - [ 教程 ](/en/tags/教程) - [Mar 23, 2026 ## 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/en/article/free-domain) - [ 白嫖 ](/en/tags/白嫖) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ cloudflare ](/en/tags/cloudflare) - [ 教程 ](/en/tags/教程) --- ## Tags: #hexo URL: https://blog.rusin7.com/en/tags/hexo View all posts with the tag - hexo # Tags: #hexo - [Jun 7, 2026 ## 在 Hexo 中复现洛谷插件 前言OIer都知道,洛谷中有个,非常好用,效果如下:succ 13 分钟 ](/en/article/luogu-plugin-in-hexo) - [ hexo ](/en/tags/hexo) - [ 安知鱼美化 ](/en/tags/安知鱼美化) - [![侧边栏添加个性定位欢迎信息](https://image.rusin7.com/file/hexo/cover/z7qOAkod.webp) Apr 6, 2026 ## 侧边栏添加个性定位欢迎信息 前景介绍使用方法创建JS文件 9 分钟](/en/article/location-welcome-information) - [ hexo ](/en/tags/hexo) - [ 安知鱼美化 ](/en/tags/安知鱼美化) - [ 建站 ](/en/tags/建站) --- ## Tags: #markdown URL: https://blog.rusin7.com/en/tags/markdown View all posts with the tag - markdown # Tags: #markdown - [Aug 31, 2026 ## Cyanwind theme markdown syntax Learn the basic syntax of Markdown from beginner to advanced. 10 分钟 en ](/en/article/how-to-use-markdown) - [ tutorial ](/en/tags/tutorial) - [ markdown ](/en/tags/markdown) - [Jan 11, 2026 ## MDX Components: User & Advanced How to use built-in content components (Aside/Tabs, etc.) and advanced widgets (LinkPreview/GithubCard, etc.). 1 分钟 en ](/en/article/mdx-components) - [ markdown ](/en/tags/markdown) - [Jan 11, 2026 ## Writing Guide: Markdown / MDX Supported Markdown extensions, KaTeX math, Shiki code features, and when to use MDX. 1 分钟 en ](/en/article/writing-markdown-mdx) - [ markdown ](/en/tags/markdown) --- ## Tags: #nodejs URL: https://blog.rusin7.com/en/tags/nodejs View all posts with the tag - nodejs # Tags: #nodejs - [Apr 19, 2026 ## 在 VS code 上远程管理 Github 仓库并自动化部署项目 如果GitHub远程是没有提交的空仓库然后再绑定哦。 7 分钟 ](/en/article/remote-github-repo-on-vs-code) - [ vs code ]() - [ git ](/en/tags/git) - [ nodejs ](/en/tags/nodejs) - [![在 arm64 中安装虚拟环境](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) Apr 3, 2026 ## 在 arm64 中安装虚拟环境 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 3 分钟](/en/article/arm64-install-base) - [ git ](/en/tags/git) - [ nodejs ](/en/tags/nodejs) - [ 教程 ](/en/tags/教程) --- ## Tags: #tutorial URL: https://blog.rusin7.com/en/tags/tutorial View all posts with the tag - tutorial # Tags: #tutorial - [Aug 31, 2026 ## Cyanwind theme markdown syntax Learn the basic syntax of Markdown from beginner to advanced. 10 分钟 en ](/en/article/how-to-use-markdown) - [ tutorial ](/en/tags/tutorial) - [ markdown ](/en/tags/markdown) --- ## Tags: #vs code URL: https://blog.rusin7.com/en/tags/vs code View all posts with the tag - vs code # Tags: #vs code - [Apr 20, 2026 ## 对单一仓库配置小号以远程管理小号仓库 命令行操作给这个仓库单独设置小号仅本地生效把远程地址绑定到小 1 分钟 ](/en/article/configure-a-single-warehouse) - [ vs code ]() - [ git ](/en/tags/git) - [Apr 19, 2026 ## 在 VS code 上远程管理 Github 仓库并自动化部署项目 如果GitHub远程是没有提交的空仓库然后再绑定哦。 7 分钟 ](/en/article/remote-github-repo-on-vs-code) - [ vs code ]() - [ git ](/en/tags/git) - [ nodejs ](/en/tags/nodejs) --- ## Tags: #云服务器 URL: https://blog.rusin7.com/en/tags/云服务器 View all posts with the tag - 云服务器 # Tags: #云服务器 - [![在 VPS 上部署洛谷保存站](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) Aug 11, 2026 ## 在 VPS 上部署洛谷保存站 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) 8 分钟](/en/article/deploy-lg-saver) - [ 云服务器 ](/en/tags/云服务器) - [ 建站 ](/en/tags/建站) - [ 教程 ](/en/tags/教程) --- ## Tags: #公告 URL: https://blog.rusin7.com/en/tags/公告 View all posts with the tag - 公告 # Tags: #公告 - [Aug 3, 2026 ## 博客迁移分流说明 博客迁移分流说明在我的陪伴大家4个月后,由于当时技术较差,不会使用 git 命令行和 node.js,所以不够美观 1 分钟 ](/en/article/explanation-of-blog-migration) - [ 公告 ](/en/tags/公告) --- ## Tags: #安知鱼美化 URL: https://blog.rusin7.com/en/tags/安知鱼美化 View all posts with the tag - 安知鱼美化 # Tags: #安知鱼美化 - [Jun 7, 2026 ## 在 Hexo 中复现洛谷插件 前言OIer都知道,洛谷中有个,非常好用,效果如下:succ 13 分钟 ](/en/article/luogu-plugin-in-hexo) - [ hexo ](/en/tags/hexo) - [ 安知鱼美化 ](/en/tags/安知鱼美化) - [![侧边栏添加个性定位欢迎信息](https://image.rusin7.com/file/hexo/cover/z7qOAkod.webp) Apr 6, 2026 ## 侧边栏添加个性定位欢迎信息 前景介绍使用方法创建JS文件 9 分钟](/en/article/location-welcome-information) - [ hexo ](/en/tags/hexo) - [ 安知鱼美化 ](/en/tags/安知鱼美化) - [ 建站 ](/en/tags/建站) --- ## Tags: #建站 URL: https://blog.rusin7.com/en/tags/建站 View all posts with the tag - 建站 # Tags: #建站 - [![Rusin note Project Recommend](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) Aug 13, 2026 ## Rusin note Project Recommend Recommend a lightweight Python project for server deployment. Welcome to submit PRs and join the development! 11 分钟 en](/en/article/rusin-note) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ 开源项目 ](/en/tags/开源项目) - [ 教程 ](/en/tags/教程) - [![在 VPS 上部署洛谷保存站](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) Aug 11, 2026 ## 在 VPS 上部署洛谷保存站 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) 8 分钟](/en/article/deploy-lg-saver) - [ 云服务器 ](/en/tags/云服务器) - [ 建站 ](/en/tags/建站) - [ 教程 ](/en/tags/教程) - [![侧边栏添加个性定位欢迎信息](https://image.rusin7.com/file/hexo/cover/z7qOAkod.webp) Apr 6, 2026 ## 侧边栏添加个性定位欢迎信息 前景介绍使用方法创建JS文件 9 分钟](/en/article/location-welcome-information) - [ hexo ](/en/tags/hexo) - [ 安知鱼美化 ](/en/tags/安知鱼美化) - [ 建站 ](/en/tags/建站) - [Mar 23, 2026 ## 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/en/article/free-domain) - [ 白嫖 ](/en/tags/白嫖) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ cloudflare ](/en/tags/cloudflare) - [ 教程 ](/en/tags/教程) --- ## Tags: #开源项目 URL: https://blog.rusin7.com/en/tags/开源项目 View all posts with the tag - 开源项目 # Tags: #开源项目 - [![Rusin note Project Recommend](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) Aug 13, 2026 ## Rusin note Project Recommend Recommend a lightweight Python project for server deployment. Welcome to submit PRs and join the development! 11 分钟 en](/en/article/rusin-note) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ 开源项目 ](/en/tags/开源项目) - [ 教程 ](/en/tags/教程) --- ## Tags: #教程 URL: https://blog.rusin7.com/en/tags/教程 View all posts with the tag - 教程 # Tags: #教程 - [![Rusin note Project Recommend](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) Aug 13, 2026 ## Rusin note Project Recommend Recommend a lightweight Python project for server deployment. Welcome to submit PRs and join the development! 11 分钟 en](/en/article/rusin-note) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ 开源项目 ](/en/tags/开源项目) - [ 教程 ](/en/tags/教程) - [![在 VPS 上部署洛谷保存站](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) Aug 11, 2026 ## 在 VPS 上部署洛谷保存站 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) 8 分钟](/en/article/deploy-lg-saver) - [ 云服务器 ](/en/tags/云服务器) - [ 建站 ](/en/tags/建站) - [ 教程 ](/en/tags/教程) - [![在 arm64 中安装虚拟环境](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) Apr 3, 2026 ## 在 arm64 中安装虚拟环境 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 3 分钟](/en/article/arm64-install-base) - [ git ](/en/tags/git) - [ nodejs ](/en/tags/nodejs) - [ 教程 ](/en/tags/教程) - [Mar 23, 2026 ## 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/en/article/free-domain) - [ 白嫖 ](/en/tags/白嫖) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ cloudflare ](/en/tags/cloudflare) - [ 教程 ](/en/tags/教程) --- ## Tags: #比赛 URL: https://blog.rusin7.com/en/tags/比赛 View all posts with the tag - 比赛 # Tags: #比赛 - [Jun 6, 2026 ## JC 提高班期末测试题解 题目描述雪花图是由两个整数x和y均大于1生成的,生成方式如下 9 分钟 ](/en/article/jc-the-end-of-class-test-solution) - [ 题解 ](/en/tags/题解) - [ 比赛 ](/en/tags/比赛) - [![第22届浙大宁波理工学院程序设计大赛题解](https://image.rusin7.com/file/hexo/cover/VdGvvMhu.webp) Apr 3, 2026 ## 第22届浙大宁波理工学院程序设计大赛题解 本文讲述了第22届浙大宁波理工学院程序设计大赛的 C++ 代码。 15 分钟](/en/article/22nd-zhejiang-competition-solution) - [ 题解 ](/en/tags/题解) - [ 比赛 ](/en/tags/比赛) --- ## Tags: #白嫖 URL: https://blog.rusin7.com/en/tags/白嫖 View all posts with the tag - 白嫖 # Tags: #白嫖 - [Mar 23, 2026 ## 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/en/article/free-domain) - [ 白嫖 ](/en/tags/白嫖) - [ 建站 ](/en/tags/建站) - [ github ](/en/tags/github) - [ cloudflare ](/en/tags/cloudflare) - [ 教程 ](/en/tags/教程) --- ## Tags: #笔记 URL: https://blog.rusin7.com/en/tags/笔记 View all posts with the tag - 笔记 # Tags: #笔记 - [Sep 29, 2026 ## 单源最短路算法 本文将会单源最短路的定义,并给出 SPFA、Bellman-Ford、Dijkstra 等多种用于求单源最短路的算法并进行比较。 11 分钟 zh ](/en/article/shortest-path) - [ c++ ](/en/tags/c++) - [ 笔记 ](/en/tags/笔记) - [Jun 7, 2026 ## 笔记——树形动态规划 若如图所示,当前dfs至点u,则转移方程得 2 分钟 ](/en/article/notes-of-dp-on-trees) - [ 笔记 ](/en/tags/笔记) - [ c++ ](/en/tags/c++) - [Jun 6, 2026 ## AC 自动机笔记 AC 自动机笔记 1 分钟 ](/en/article/automated-ac) - [ 笔记 ](/en/tags/笔记) - [ c++ ](/en/tags/c++) - [Jun 6, 2026 ## 网络流笔记 增广路ek模板Dinic模板,网络流的定义 15 分钟 ](/en/article/the-network-flow-notes) - [ 笔记 ](/en/tags/笔记) - [ c++ ](/en/tags/c++) --- ## Tags: #美文 URL: https://blog.rusin7.com/en/tags/美文 View all posts with the tag - 美文 # Tags: #美文 - [Apr 3, 2026 ## 我常常追忆过去 我将背后的时间裁剪、折叠、蜷曲,揉捻成天上朵朵白云。 2 分钟 ](/en/article/remember-the-past) - [ 美文 ](/en/tags/美文) --- ## Tags: #题解 URL: https://blog.rusin7.com/en/tags/题解 View all posts with the tag - 题解 # Tags: #题解 - [![题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 ## 题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ! 本文讲述了如何使用 C++ 完成洛谷的 AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!,思路清晰、排版精美 4 分钟](/en/article/at-pakencamp-2020-day1-d-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [Jun 6, 2026 ## JC 提高班期末测试题解 题目描述雪花图是由两个整数x和y均大于1生成的,生成方式如下 9 分钟 ](/en/article/jc-the-end-of-class-test-solution) - [ 题解 ](/en/tags/题解) - [ 比赛 ](/en/tags/比赛) - [![题解:P13361 \[GCJ 2011 Qualification\] Bot Trust](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 ## 题解:P13361 \[GCJ 2011 Qualification\] Bot Trust 本文讲述了如何使用 C++ 完成洛谷的 P13361 \[GCJ 2011 Qualification\] Bot Trust」水落溪流浅浅,思路清晰、排版精美 4 分钟](/en/article/p13361-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P8506 标题计数](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 ## 题解:P8506 标题计数 本文讲述了如何使用 C++ 完成洛谷的 P8506 标题计数,思路清晰、排版精美 3 分钟](/en/article/p8506-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P8534 「Wdoi-2」比赤色更红的梦](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Jun 6, 2026 ## 题解:P8534 「Wdoi-2」比赤色更红的梦 本文讲述了如何使用 C++ 完成洛谷的 P8534 「Wdoi-2」比赤色更红的梦,思路清晰、排版精美 2 分钟](/en/article/p8534-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![第22届浙大宁波理工学院程序设计大赛题解](https://image.rusin7.com/file/hexo/cover/VdGvvMhu.webp) Apr 3, 2026 ## 第22届浙大宁波理工学院程序设计大赛题解 本文讲述了第22届浙大宁波理工学院程序设计大赛的 C++ 代码。 15 分钟](/en/article/22nd-zhejiang-competition-solution) - [ 题解 ](/en/tags/题解) - [ 比赛 ](/en/tags/比赛) - [![题解:P14702 \[ICPC 2024 Tehran R\] Boat](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Apr 3, 2026 ## 题解:P14702 \[ICPC 2024 Tehran R\] Boat 本文讲述了如何使用 C++ 完成洛谷的 题解:P14702 \[ICPC 2024 Tehran R\] Boat,思路清晰、排版精美 2 分钟](/en/article/p14702-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Apr 3, 2026 ## 题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree 本文讲述了如何使用 C++ 完成洛谷的 P14731 \[ICPC 2022 Seoul R\] Parentheses Tree,思路清晰、排版精美 2 分钟](/en/article/p14731-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:AT\_joi2024\_yo1c\_b 桁 (Digit)](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 30, 2026 ## 题解:AT\_joi2024\_yo1c\_b 桁 (Digit) 本文讲述了如何使用 C++ 完成洛谷的 AT\_joi2024\_yo1c\_b 桁 (Digit),思路清晰、排版精美 1 分钟](/en/article/at-joi2024) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 30, 2026 ## 题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type 本文讲述了如何使用 C++ 完成洛谷的 P14730 \[ICPC 2022 Seoul R\] Palindrome Type,思路清晰、排版精美 2 分钟](/en/article/p14730-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) - [![题解:CF2139B Cake Collection](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) Mar 23, 2026 ## 题解:CF2139B Cake Collection 本文讲述了如何使用 C++ 完成洛谷的 CF2139B Cake Collection,思路清晰、排版精美 3 分钟](/en/article/cf2139b-sol) - [ 题解 ](/en/tags/题解) - [ c++ ](/en/tags/c++) --- ## Tags: #c++ URL: https://blog.rusin7.com/tags/c++ View all posts with the tag - c++ # Tags: #c++ - [2026/09/29 ## 单源最短路算法 本文将会单源最短路的定义,并给出 SPFA、Bellman-Ford、Dijkstra 等多种用于求单源最短路的算法并进行比较。 11 分钟 zh ](/article/shortest-path) - [ c++ ](/tags/c++) - [ 笔记 ](/tags/笔记) - [2026/07/22 ## 洛谷网校 CSP 初赛笔记 笔记 2 分钟 ](/article/luogu-class-csp-j-note) - [ c++ ](/tags/c++) - [2026/06/07 ## 笔记——树形动态规划 若如图所示,当前dfs至点u,则转移方程得 2 分钟 ](/article/notes-of-dp-on-trees) - [ 笔记 ](/tags/笔记) - [ c++ ](/tags/c++) - [![题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 ## 题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ! 本文讲述了如何使用 C++ 完成洛谷的 AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!,思路清晰、排版精美 4 分钟](/article/at-pakencamp-2020-day1-d-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [2026/06/06 ## AC 自动机笔记 AC 自动机笔记 1 分钟 ](/article/automated-ac) - [ 笔记 ](/tags/笔记) - [ c++ ](/tags/c++) - [![题解:P13361 \[GCJ 2011 Qualification\] Bot Trust](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 ## 题解:P13361 \[GCJ 2011 Qualification\] Bot Trust 本文讲述了如何使用 C++ 完成洛谷的 P13361 \[GCJ 2011 Qualification\] Bot Trust」水落溪流浅浅,思路清晰、排版精美 4 分钟](/article/p13361-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P8506 标题计数](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 ## 题解:P8506 标题计数 本文讲述了如何使用 C++ 完成洛谷的 P8506 标题计数,思路清晰、排版精美 3 分钟](/article/p8506-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P8534 「Wdoi-2」比赤色更红的梦](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 ## 题解:P8534 「Wdoi-2」比赤色更红的梦 本文讲述了如何使用 C++ 完成洛谷的 P8534 「Wdoi-2」比赤色更红的梦,思路清晰、排版精美 2 分钟](/article/p8534-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [2026/06/06 ## 网络流笔记 增广路ek模板Dinic模板,网络流的定义 15 分钟 ](/article/the-network-flow-notes) - [ 笔记 ](/tags/笔记) - [ c++ ](/tags/c++) - [![图论之欧拉回路、差分约束——算法笔记](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/04/03 ## 图论之欧拉回路、差分约束——算法笔记 本文讲述了图论之欧拉回路、差分约束的 C++ 代码,并推荐了比赛和题目以便练习。 2 分钟](/article/euro-circuit-notes) - [ c++ ](/tags/c++) - [![题解:P14702 \[ICPC 2024 Tehran R\] Boat](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/04/03 ## 题解:P14702 \[ICPC 2024 Tehran R\] Boat 本文讲述了如何使用 C++ 完成洛谷的 题解:P14702 \[ICPC 2024 Tehran R\] Boat,思路清晰、排版精美 2 分钟](/article/p14702-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/04/03 ## 题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree 本文讲述了如何使用 C++ 完成洛谷的 P14731 \[ICPC 2022 Seoul R\] Parentheses Tree,思路清晰、排版精美 2 分钟](/article/p14731-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:AT\_joi2024\_yo1c\_b 桁 (Digit)](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/30 ## 题解:AT\_joi2024\_yo1c\_b 桁 (Digit) 本文讲述了如何使用 C++ 完成洛谷的 AT\_joi2024\_yo1c\_b 桁 (Digit),思路清晰、排版精美 1 分钟](/article/at-joi2024) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/30 ## 题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type 本文讲述了如何使用 C++ 完成洛谷的 P14730 \[ICPC 2022 Seoul R\] Palindrome Type,思路清晰、排版精美 2 分钟](/article/p14730-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:CF2139B Cake Collection](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/23 ## 题解:CF2139B Cake Collection 本文讲述了如何使用 C++ 完成洛谷的 CF2139B Cake Collection,思路清晰、排版精美 3 分钟](/article/cf2139b-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) --- ## Tags: #cloudflare URL: https://blog.rusin7.com/tags/cloudflare View all posts with the tag - cloudflare # Tags: #cloudflare - [2026/03/23 ## 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/article/free-domain) - [ 白嫖 ](/tags/白嫖) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ cloudflare ](/tags/cloudflare) - [ 教程 ](/tags/教程) --- ## Tags: #git URL: https://blog.rusin7.com/tags/git View all posts with the tag - git # Tags: #git - [2026/05/14 ## 拯救谷歌和 Github!你的新“自行车” 快速安装,找到最新版本,安装包选择方式:Windows:De 1 分钟 ](/article/devsidecar) - [ git ](/tags/git) - [2026/05/12 ## Vercel 仅部署指定分支的方法 如何指定特殊分支? 从中选择的项目,在侧边栏中打开Settings 3 分钟 ](/article/vercel-deploying-only-1-branch) - [ git ](/tags/git) - [2026/04/20 ## 对单一仓库配置小号以远程管理小号仓库 命令行操作给这个仓库单独设置小号仅本地生效把远程地址绑定到小 1 分钟 ](/article/configure-a-single-warehouse) - [ vs code ]() - [ git ](/tags/git) - [2026/04/19 ## 在 VS code 上远程管理 Github 仓库并自动化部署项目 如果GitHub远程是没有提交的空仓库然后再绑定哦。 7 分钟 ](/article/remote-github-repo-on-vs-code) - [ vs code ]() - [ git ](/tags/git) - [ nodejs ](/tags/nodejs) - [![在 arm64 中安装虚拟环境](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) 2026/04/03 ## 在 arm64 中安装虚拟环境 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 3 分钟](/article/arm64-install-base) - [ git ](/tags/git) - [ nodejs ](/tags/nodejs) - [ 教程 ](/tags/教程) --- ## Tags: #github URL: https://blog.rusin7.com/tags/github View all posts with the tag - github # Tags: #github - [![Rusin note 项目推荐](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) 2026/08/13 ## Rusin note 项目推荐 推荐一个轻量的服务器部署 python 项目,欢迎大家交 PR,一起开发! 21 分钟 zh](/article/rusin-note) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ 开源项目 ](/tags/开源项目) - [ 教程 ](/tags/教程) - [2026/03/23 ## 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/article/free-domain) - [ 白嫖 ](/tags/白嫖) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ cloudflare ](/tags/cloudflare) - [ 教程 ](/tags/教程) --- ## Tags: #hexo URL: https://blog.rusin7.com/tags/hexo View all posts with the tag - hexo # Tags: #hexo - [2026/06/07 ## 在 Hexo 中复现洛谷插件 前言OIer都知道,洛谷中有个,非常好用,效果如下:succ 13 分钟 ](/article/luogu-plugin-in-hexo) - [ hexo ](/tags/hexo) - [ 安知鱼美化 ](/tags/安知鱼美化) - [![侧边栏添加个性定位欢迎信息](https://image.rusin7.com/file/hexo/cover/z7qOAkod.webp) 2026/04/06 ## 侧边栏添加个性定位欢迎信息 前景介绍使用方法创建JS文件 9 分钟](/article/location-welcome-information) - [ hexo ](/tags/hexo) - [ 安知鱼美化 ](/tags/安知鱼美化) - [ 建站 ](/tags/建站) --- ## Tags: #markdown URL: https://blog.rusin7.com/tags/markdown View all posts with the tag - markdown # Tags: #markdown - [2026/08/31 ## Cyanwind 主题 markdown 语法 学习 Markdown 的基础语法,从入门到精通。 17 分钟 zh ](/article/how-to-use-markdown) - [ 教程 ](/tags/教程) - [ markdown ](/tags/markdown) - [2026/01/11 ## MDX 组件使用:User & Advanced 文章内组件(Aside/Tabs 等)与高级组件(LinkPreview/GithubCard 等)的使用方式。 1 分钟 zh ](/article/mdx-components) - [ markdown ](/tags/markdown) - [2026/01/11 ## 写作指南:Markdown / MDX 主题内支持的 Markdown 扩展、数学公式、代码高亮与一些写作约定。 1 分钟 zh ](/article/writing-markdown-mdx) - [ markdown ](/tags/markdown) --- ## Tags: #nodejs URL: https://blog.rusin7.com/tags/nodejs View all posts with the tag - nodejs # Tags: #nodejs - [2026/04/19 ## 在 VS code 上远程管理 Github 仓库并自动化部署项目 如果GitHub远程是没有提交的空仓库然后再绑定哦。 7 分钟 ](/article/remote-github-repo-on-vs-code) - [ vs code ]() - [ git ](/tags/git) - [ nodejs ](/tags/nodejs) - [![在 arm64 中安装虚拟环境](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) 2026/04/03 ## 在 arm64 中安装虚拟环境 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 3 分钟](/article/arm64-install-base) - [ git ](/tags/git) - [ nodejs ](/tags/nodejs) - [ 教程 ](/tags/教程) --- ## Tags: #vs code URL: https://blog.rusin7.com/tags/vs code View all posts with the tag - vs code # Tags: #vs code - [2026/04/20 ## 对单一仓库配置小号以远程管理小号仓库 命令行操作给这个仓库单独设置小号仅本地生效把远程地址绑定到小 1 分钟 ](/article/configure-a-single-warehouse) - [ vs code ]() - [ git ](/tags/git) - [2026/04/19 ## 在 VS code 上远程管理 Github 仓库并自动化部署项目 如果GitHub远程是没有提交的空仓库然后再绑定哦。 7 分钟 ](/article/remote-github-repo-on-vs-code) - [ vs code ]() - [ git ](/tags/git) - [ nodejs ](/tags/nodejs) --- ## Tags: #云服务器 URL: https://blog.rusin7.com/tags/云服务器 View all posts with the tag - 云服务器 # Tags: #云服务器 - [![在 VPS 上部署洛谷保存站](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) 2026/08/11 ## 在 VPS 上部署洛谷保存站 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) 8 分钟](/article/deploy-lg-saver) - [ 云服务器 ](/tags/云服务器) - [ 建站 ](/tags/建站) - [ 教程 ](/tags/教程) --- ## Tags: #公告 URL: https://blog.rusin7.com/tags/公告 View all posts with the tag - 公告 # Tags: #公告 - [2026/08/03 ## 博客迁移分流说明 博客迁移分流说明在我的陪伴大家4个月后,由于当时技术较差,不会使用 git 命令行和 node.js,所以不够美观 1 分钟 ](/article/explanation-of-blog-migration) - [ 公告 ](/tags/公告) --- ## Tags: #安知鱼美化 URL: https://blog.rusin7.com/tags/安知鱼美化 View all posts with the tag - 安知鱼美化 # Tags: #安知鱼美化 - [2026/06/07 ## 在 Hexo 中复现洛谷插件 前言OIer都知道,洛谷中有个,非常好用,效果如下:succ 13 分钟 ](/article/luogu-plugin-in-hexo) - [ hexo ](/tags/hexo) - [ 安知鱼美化 ](/tags/安知鱼美化) - [![侧边栏添加个性定位欢迎信息](https://image.rusin7.com/file/hexo/cover/z7qOAkod.webp) 2026/04/06 ## 侧边栏添加个性定位欢迎信息 前景介绍使用方法创建JS文件 9 分钟](/article/location-welcome-information) - [ hexo ](/tags/hexo) - [ 安知鱼美化 ](/tags/安知鱼美化) - [ 建站 ](/tags/建站) --- ## Tags: #建站 URL: https://blog.rusin7.com/tags/建站 View all posts with the tag - 建站 # Tags: #建站 - [![Rusin note 项目推荐](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) 2026/08/13 ## Rusin note 项目推荐 推荐一个轻量的服务器部署 python 项目,欢迎大家交 PR,一起开发! 21 分钟 zh](/article/rusin-note) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ 开源项目 ](/tags/开源项目) - [ 教程 ](/tags/教程) - [![在 VPS 上部署洛谷保存站](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) 2026/08/11 ## 在 VPS 上部署洛谷保存站 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) 8 分钟](/article/deploy-lg-saver) - [ 云服务器 ](/tags/云服务器) - [ 建站 ](/tags/建站) - [ 教程 ](/tags/教程) - [![侧边栏添加个性定位欢迎信息](https://image.rusin7.com/file/hexo/cover/z7qOAkod.webp) 2026/04/06 ## 侧边栏添加个性定位欢迎信息 前景介绍使用方法创建JS文件 9 分钟](/article/location-welcome-information) - [ hexo ](/tags/hexo) - [ 安知鱼美化 ](/tags/安知鱼美化) - [ 建站 ](/tags/建站) - [2026/03/23 ## 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/article/free-domain) - [ 白嫖 ](/tags/白嫖) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ cloudflare ](/tags/cloudflare) - [ 教程 ](/tags/教程) --- ## Tags: #开源项目 URL: https://blog.rusin7.com/tags/开源项目 View all posts with the tag - 开源项目 # Tags: #开源项目 - [![Rusin note 项目推荐](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) 2026/08/13 ## Rusin note 项目推荐 推荐一个轻量的服务器部署 python 项目,欢迎大家交 PR,一起开发! 21 分钟 zh](/article/rusin-note) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ 开源项目 ](/tags/开源项目) - [ 教程 ](/tags/教程) --- ## Tags: #教程 URL: https://blog.rusin7.com/tags/教程 View all posts with the tag - 教程 # Tags: #教程 - [2026/08/31 ## Cyanwind 主题 markdown 语法 学习 Markdown 的基础语法,从入门到精通。 17 分钟 zh ](/article/how-to-use-markdown) - [ 教程 ](/tags/教程) - [ markdown ](/tags/markdown) - [![Rusin note 项目推荐](https://image.rusin7.com/file/hexo/cover/FCskF2aQ.webp) 2026/08/13 ## Rusin note 项目推荐 推荐一个轻量的服务器部署 python 项目,欢迎大家交 PR,一起开发! 21 分钟 zh](/article/rusin-note) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ 开源项目 ](/tags/开源项目) - [ 教程 ](/tags/教程) - [![在 VPS 上部署洛谷保存站](https://image.rusin7.com/file/hexo/cover/vpqG4xgg.webp) 2026/08/11 ## 在 VPS 上部署洛谷保存站 本文讲述了如何在 Zeabur 上购买腾讯云服务器并使用 VPS 通过 Docker 镜像部署 (无需实名) 8 分钟](/article/deploy-lg-saver) - [ 云服务器 ](/tags/云服务器) - [ 建站 ](/tags/建站) - [ 教程 ](/tags/教程) - [![在 arm64 中安装虚拟环境](https://image.rusin7.com/file/hexo/cover/Dpl8bPpL.webp) 2026/04/03 ## 在 arm64 中安装虚拟环境 本文讲述了然如何在 arm64 系统上安装虚拟环境、NodeJs 和 Git。 3 分钟](/article/arm64-install-base) - [ git ](/tags/git) - [ nodejs ](/tags/nodejs) - [ 教程 ](/tags/教程) - [2026/03/23 ## 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/article/free-domain) - [ 白嫖 ](/tags/白嫖) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ cloudflare ](/tags/cloudflare) - [ 教程 ](/tags/教程) --- ## Tags: #比赛 URL: https://blog.rusin7.com/tags/比赛 View all posts with the tag - 比赛 # Tags: #比赛 - [2026/06/06 ## JC 提高班期末测试题解 题目描述雪花图是由两个整数x和y均大于1生成的,生成方式如下 9 分钟 ](/article/jc-the-end-of-class-test-solution) - [ 题解 ](/tags/题解) - [ 比赛 ](/tags/比赛) - [![第22届浙大宁波理工学院程序设计大赛题解](https://image.rusin7.com/file/hexo/cover/VdGvvMhu.webp) 2026/04/03 ## 第22届浙大宁波理工学院程序设计大赛题解 本文讲述了第22届浙大宁波理工学院程序设计大赛的 C++ 代码。 15 分钟](/article/22nd-zhejiang-competition-solution) - [ 题解 ](/tags/题解) - [ 比赛 ](/tags/比赛) --- ## Tags: #白嫖 URL: https://blog.rusin7.com/tags/白嫖 View all posts with the tag - 白嫖 # Tags: #白嫖 - [2026/03/23 ## 免费获取二级域名并部署 github 仓库 本教程介绍了如何免费给博客获取域名,并提供了注册、获取、托管详细步骤及技术支持方式。教程的内容针对新 UI 进行更新,配图丰富。 5 分钟 ](/article/free-domain) - [ 白嫖 ](/tags/白嫖) - [ 建站 ](/tags/建站) - [ github ](/tags/github) - [ cloudflare ](/tags/cloudflare) - [ 教程 ](/tags/教程) --- ## Tags: #笔记 URL: https://blog.rusin7.com/tags/笔记 View all posts with the tag - 笔记 # Tags: #笔记 - [2026/09/29 ## 单源最短路算法 本文将会单源最短路的定义,并给出 SPFA、Bellman-Ford、Dijkstra 等多种用于求单源最短路的算法并进行比较。 11 分钟 zh ](/article/shortest-path) - [ c++ ](/tags/c++) - [ 笔记 ](/tags/笔记) - [2026/06/07 ## 笔记——树形动态规划 若如图所示,当前dfs至点u,则转移方程得 2 分钟 ](/article/notes-of-dp-on-trees) - [ 笔记 ](/tags/笔记) - [ c++ ](/tags/c++) - [2026/06/06 ## AC 自动机笔记 AC 自动机笔记 1 分钟 ](/article/automated-ac) - [ 笔记 ](/tags/笔记) - [ c++ ](/tags/c++) - [2026/06/06 ## 网络流笔记 增广路ek模板Dinic模板,网络流的定义 15 分钟 ](/article/the-network-flow-notes) - [ 笔记 ](/tags/笔记) - [ c++ ](/tags/c++) --- ## Tags: #美文 URL: https://blog.rusin7.com/tags/美文 View all posts with the tag - 美文 # Tags: #美文 - [2026/04/03 ## 我常常追忆过去 我将背后的时间裁剪、折叠、蜷曲,揉捻成天上朵朵白云。 2 分钟 ](/article/remember-the-past) - [ 美文 ](/tags/美文) --- ## Tags: #题解 URL: https://blog.rusin7.com/tags/题解 View all posts with the tag - 题解 # Tags: #题解 - [![题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 ## 题解:AT\_pakencamp\_2020\_day1\_d 立方体を壊せ! 本文讲述了如何使用 C++ 完成洛谷的 AT\_pakencamp\_2020\_day1\_d 立方体を壊せ!,思路清晰、排版精美 4 分钟](/article/at-pakencamp-2020-day1-d-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [2026/06/06 ## JC 提高班期末测试题解 题目描述雪花图是由两个整数x和y均大于1生成的,生成方式如下 9 分钟 ](/article/jc-the-end-of-class-test-solution) - [ 题解 ](/tags/题解) - [ 比赛 ](/tags/比赛) - [![题解:P13361 \[GCJ 2011 Qualification\] Bot Trust](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 ## 题解:P13361 \[GCJ 2011 Qualification\] Bot Trust 本文讲述了如何使用 C++ 完成洛谷的 P13361 \[GCJ 2011 Qualification\] Bot Trust」水落溪流浅浅,思路清晰、排版精美 4 分钟](/article/p13361-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P8506 标题计数](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 ## 题解:P8506 标题计数 本文讲述了如何使用 C++ 完成洛谷的 P8506 标题计数,思路清晰、排版精美 3 分钟](/article/p8506-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P8534 「Wdoi-2」比赤色更红的梦](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/06/06 ## 题解:P8534 「Wdoi-2」比赤色更红的梦 本文讲述了如何使用 C++ 完成洛谷的 P8534 「Wdoi-2」比赤色更红的梦,思路清晰、排版精美 2 分钟](/article/p8534-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![第22届浙大宁波理工学院程序设计大赛题解](https://image.rusin7.com/file/hexo/cover/VdGvvMhu.webp) 2026/04/03 ## 第22届浙大宁波理工学院程序设计大赛题解 本文讲述了第22届浙大宁波理工学院程序设计大赛的 C++ 代码。 15 分钟](/article/22nd-zhejiang-competition-solution) - [ 题解 ](/tags/题解) - [ 比赛 ](/tags/比赛) - [![题解:P14702 \[ICPC 2024 Tehran R\] Boat](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/04/03 ## 题解:P14702 \[ICPC 2024 Tehran R\] Boat 本文讲述了如何使用 C++ 完成洛谷的 题解:P14702 \[ICPC 2024 Tehran R\] Boat,思路清晰、排版精美 2 分钟](/article/p14702-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/04/03 ## 题解:P14731 \[ICPC 2022 Seoul R\] Parentheses Tree 本文讲述了如何使用 C++ 完成洛谷的 P14731 \[ICPC 2022 Seoul R\] Parentheses Tree,思路清晰、排版精美 2 分钟](/article/p14731-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:AT\_joi2024\_yo1c\_b 桁 (Digit)](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/30 ## 题解:AT\_joi2024\_yo1c\_b 桁 (Digit) 本文讲述了如何使用 C++ 完成洛谷的 AT\_joi2024\_yo1c\_b 桁 (Digit),思路清晰、排版精美 1 分钟](/article/at-joi2024) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/30 ## 题解:P14730 \[ICPC 2022 Seoul R\] Palindrome Type 本文讲述了如何使用 C++ 完成洛谷的 P14730 \[ICPC 2022 Seoul R\] Palindrome Type,思路清晰、排版精美 2 分钟](/article/p14730-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++) - [![题解:CF2139B Cake Collection](https://image.rusin7.com/file/hexo/cover/kuKbfhkc.webp) 2026/03/23 ## 题解:CF2139B Cake Collection 本文讲述了如何使用 C++ 完成洛谷的 CF2139B Cake Collection,思路清晰、排版精美 3 分钟](/article/cf2139b-sol) - [ 题解 ](/tags/题解) - [ c++ ](/tags/c++)