<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
<channel>
<atom:link href="https://snowflake.pink/feed" rel="self" type="application/rss+xml"/>
<title>粉粉何所似？</title>
<link>https://snowflake.pink</link>
<description>A Site of Snowflake_Pink</description>
<language>zh-CN</language>
<copyright>© Snowflake_Pink </copyright>
<pubDate>Wed, 11 Mar 2026 11:25:14 GMT</pubDate>
<generator>Mix Space CMS (https://github.com/mx-space)</generator>
<docs>https://mx-space.js.org</docs>
<image>
    <url>https://cdn.snowflake.pink/avatar.jpg</url>
    <title>粉粉何所似？</title>
    <link>https://snowflake.pink</link>
</image>
<item>
    <title>25  Week 30</title>
    <link>https://snowflake.pink/notes/14</link>
    <pubDate>Sun, 27 Jul 2025 16:09:47 GMT</pubDate>
    <description>坐在返校的滴滴上，耳机里正放着素颜，正好明天暑校开始，今天是周日，一些杂七杂八的事情也忙完了，该是去</description>
    <content:encoded><![CDATA[
      <blockquote>该渲染由 marked 生成，可能存在排版问题，最佳体验请前往：<a href='https://snowflake.pink/notes/14'>https://snowflake.pink/notes/14</a></blockquote>
      <p>坐在返校的滴滴上，耳机里正放着素颜，正好明天暑校开始，今天是周日，一些杂七杂八的事情也忙完了，该是去写一篇周记记录一下了。</p>
<p>回想一下这周做的事，再次返校、四天义工、最后两天和几个老同学又漂流了一次。义工一连连续了小四天，实际大概做满了 3 天，认识了一些师兄师姐，我几乎是这次会议义工唯一的本科生。多聊，多看，多做，总能带来一些新的体验和思考。我四天中对他们那种老练的社交面貌深加敬佩，谈吐之间都是</p>
<p>（29日夜续笔）</p>
<p>做义工时最高兴的事莫过于认识两位师姐了，和前辈聊天，感受她们的聊天习惯，情绪以及背后的人生轨迹，总能充实我心中对各种问题的思考。她们都是研一的研究生，8月底就要搬去五山校区，我和她们的交集大概也就仅限于那4天了，但好在那段时间无论是工作还是闲聊都相处非常愉快，最后一起在餐桌合影，也加上了微信，也没有什么可遗憾和多想的了。</p>
<p>当时我们组的负责人是贺哥，我很敬仰他的业务能力和情商，研究生基本也算是大半个身子进入社会了，希望我尽早也能沉淀出那样厚实的能力。</p>
<p>但我很显然也无法一蹴而就地达到那种 social 的能力和心态，望洋后我一如既往选择兴叹，一边兴叹一边去清远和同学漂流去了。几个初中同学的印象和七八年前也大差不差，其中好几个也是经常联系的，生疏感几乎没有。唯一比较生疏的是整个暑假里，几个大二生之间约时间出去一天，竟然只有26 27两天，大家都很忙。</p>
<p>我漂流中还途遇了一个小男孩，他的瓢大概是漂流的时候没拿稳掉了，和我挨在一起的时候，就拿了个水瓶当成武器打“水仗”。但让我感到钦佩的是，他只是一边笑着一遍用开玩笑的语气和我说，“我给你们船加水，让你们沉下去”（那个皮筏艇本来就是进水但不会沉的）。他真的在尽可能地享受这整个过程，哪怕出了丢掉水瓢不能泼水的意外。我当时没这么感性，但我能感受到什么，漂流哪能不打水仗的呢？恰好我和我一条皮筏的同学都花了十块钱买了个小瓢，我也泼累了，就把我的小瓢送给他玩了。这当然不能证明我有多善良，但是我看到他对我说谢谢谢谢和笑容时我好像能感同身受地感受到小朋友的快乐。还有他的父亲（和小朋友一条船），他知道一个瓢只需要十块钱，但漂流中是不可能再能花钱买一个了，能得到一个陌生人的相助，心中的感激想必也是无与伦比的。把瓢给小朋友后，小朋友很仗义地没拿我的水瓢泼我（哈哈），我说我可是你队友。过了一小会，我和同伴先漂下一个湾，然后第二个，然后和他们再也不见了。</p>
<p>周日最后还修了一下数模作业的论文，那位作论文手的女同学认真的有点可爱。看她生日信息，似乎一个月前才刚成年，祝她能顺利应付成年人的各种琐事吧。</p>
<p>太困了，就这样吧，已经7月30凌晨了，第二天还有课。</p>

      <p style='text-align: right'>
      <a href='https://snowflake.pink/notes/14#comments'>看完了？说点什么呢</a>
      </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">68864f4b0bb6d63f1306282f</guid>
  <category>notes</category>
false
 </item>
  <item>
    <title>又一年 6 月 9 日</title>
    <link>https://snowflake.pink/notes/13</link>
    <pubDate>Mon, 09 Jun 2025 12:41:01 GMT</pubDate>
    <description>又一年 6 月 9 日，我有点忘记去年的 6 月 9 日出考场后我进行了怎样的庆祝，但我对前年还保留</description>
    <content:encoded><![CDATA[
      <blockquote>该渲染由 marked 生成，可能存在排版问题，最佳体验请前往：<a href='https://snowflake.pink/notes/13'>https://snowflake.pink/notes/13</a></blockquote>
      <p>又一年 6 月 9 日，我有点忘记去年的 6 月 9 日出考场后我进行了怎样的庆祝，但我对前年还保留些许记忆。</p>
<p>去年那日我是中午就走的，作为班上唯一的化地生，我好像迅速地回到了宿舍拿了个充电线还是充电宝，向着吃完饭的其他同学偷偷送着加油的祝福（怕被海碰见，担心他认为我的出现会扰乱军心）。下午还有考试，因此我是不能中午回到教室去拿东西了。我的一个小书架、各种卷子、作文素材，除了几本用心书写的笔记被提前拿出来外，他们都永远留在了那个教室。</p>
<p>我大概 1 点回到小学那边的复习室，向外看着，不多时，海便来送手机给我了。我也到了离开的时候了。</p>
<p>我和海都知道这是最后一次再见面了，郑重地告了别，我看到了他难得的微笑，他也是。出门左转，到那个楼梯的拐角，我记得很久。属于我的 6 月 9 日结束了。</p>
<p>那一年很充实，一群成年人在一起，在他们的第一岁淬火重炼。那一年不是重蹈覆辙、重新来过，而是一份额外的经历和精神财富。我在那一年是乐观的，他们也是，我有幸能和他们一起。他们有屏蔽，有清北，也有像我一样的普通人。我很佩服他们的天分、他们的毅力、他们的坚持，那可能是我与这类人共事最近的一次，未来的我会怎样呢？我不好说。但是我也尝试去学会了他们身上的那种品质，这是与我无法割舍的。我在那里也看到了悲观的一幕，学校每处的栏杆与天花板间都拉满了铁丝网，两周一次的释放对于那些未成年人来说，他们的内心又会被束缚出怎样的勒痕？那年似乎充斥着恐怖，在各个角落。唯一可以渗漏自己情绪的地方，是那零星几个电话座。那里不乏笑语，但我印象更深刻地是那些倾诉，那些灵魂渴望依靠寻找出口的愤怨。我仍记得在我的一次控诉中，一位大概三四年级的孩子拍拍我的肩膀，问：”哥哥你打完了吗”。她那眼神中渴望，让我不忍想到了她多年后的自己，会不会也遭遇像我一样的磨砺或是痛苦呢。那些群体我感到很可怜，更可怜的是他们或许以后并不会认为这可怜。我一向以为这些群体离我很远，我也自认为自己也是食人间烟火，有基层经历的干部。但当我真正和他们走在一起的时候，那种个体的灵性和生命的可爱在有时让我不忍引起这些感慨。我属于那两个班，他们属于另一个世界。</p>
<p>我是无能为力的，我现在甚至还无法照顾好自己，我也不是那种有大爱的人，让另一个世界变得更加美好。回到去年 6 月 9 日，我清楚地记得我没有过多的喜悦，似乎只有压力释放带来的释然。我知道我结束了一个阶段，我可以临时的庆祝一下，但我还记得过几天后的各类自招。我从前年踏上高铁的那一刻，我似乎就明白了我以后只能一直前进，人生的乐趣只会在于前进时路过的风景、一段时间内陪行的同伴、一个阶段结束后的松弛、汗水分泌后大脑补偿赠送的多巴胺。每一次经历都只有一次，重复的经历也并不完全相同。我尽可能不想让我重入那些不热爱的痛苦，对我爱的人也是。</p>
<p>又一年 6 月 9 日。不知道静专在今天的此时此刻又有何想？他这样层次的同学能否与我再产生些许共鸣？明天的此时，他可能会开始继续为着强基计划而鼓出最后一份力？我祝福他能做到。</p>
<p>海其实很爱笑，每次都会笑吟吟地迎面他的女儿，和同事的聊天中也不乏热情与风度，他的语文课虽然内容只有那些用来选拔的知识，但仍能让人嗅到他作为一名语文老师本身散发的气质风雅、文化底蕴。我敬佩他能在自己的工作中独当一面，一复一日，年复一年，用茶水抚平睡眠的褶皱，却依然能在摞摞教案中保持着一股文人的精气神、风雅劲。我不知道他是否真的喜欢这样的生活，但是我能看到他会在奔波中尽可能地享受这一切，享受一批批的人，更重要的是，他背后也有一个家，那个他笑脸相迎的女儿。当时我和一些同学调侃，海的女儿也要在这里上小学，一直到高中一条龙吗？笑声之余，我们都知道他的努力是为了让他爱的人过的更好。我喜欢这种平凡生活中不平凡的伟大。</p>
<p>孙D老师很厉害，她是个高层次的人才，我们平时仰慕她所说的大学生活，工作经历的丰富有趣。至于那些故事让我窥见一斑还是管中窥豹，只能让我自己攀登去体察。</p>
<p>那年还有很多人，很多事，等我慢慢想起，升起兴致，再来朝花夕拾。</p>
<hr>
<p>我在大学这一年还时常想起高中时赵同学的话，大概是“生在 七八月比九月更赚”，因为相当于差不多早一年进入认知、进入学习、进入社会，那九月份的孩子岂不是白白浪费一年时光在等待？我当时便认为这非常可笑，自己经历的时间怎能算是浪费？去年的那群人中也不乏 9 月的，甚至有更早一年的同学，也有 08 年的神童（她是 34 名）。我若没有这一年，大概也不会遇到同年级的“学弟学妹”了。</p>
<p>今年 6 月 9 日，我又成长了一年，我似乎也开始担起了一些责任，并渴望担任一些更大的责任。我结识了很多人，我希望我能学会去做更多的事，享受更多从未体验的乐趣。期末周已然临近，以此为伊始，又一年。</p>
<hr>
<p>2025 年 6 月 9 日 20:40
于华工国际图书馆</p>

      <p style='text-align: right'>
      <a href='https://snowflake.pink/notes/13#comments'>看完了？说点什么呢</a>
      </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">6846d65d0bb6d63f1303a87a</guid>
  <category>notes</category>
false
 </item>
  <item>
    <title>My PR merged 10 minutes ago, where will the branch of my life be merged to?</title>
    <link>https://snowflake.pink/notes/11</link>
    <pubDate>Sun, 06 Apr 2025 16:02:45 GMT</pubDate>
    <description>https://github.com/Samueli924/chaoxing/commit/a3f5</description>
    <content:encoded><![CDATA[
      <blockquote>该渲染由 marked 生成，可能存在排版问题，最佳体验请前往：<a href='https://snowflake.pink/notes/11'>https://snowflake.pink/notes/11</a></blockquote>
      <p><a href="https://github.com/Samueli924/chaoxing/commit/a3f58e9dfb5d4f2f57be7f500ff381ff7a60625c">https://github.com/Samueli924/chaoxing/commit/a3f58e9dfb5d4f2f57be7f500ff381ff7a60625c</a></p>
<p></p>
<p>这次的 PR 提交后，十分钟就被开发者 Merge 了。</p>
<hr>
<p>我很享受这种 Create Pull Request——Review——Merged 的过程，Git 的工作流正如同软件世界里面的每一行代码一样优雅。</p>
<p>我小学三年级结束时，家委准备同学纪念册，里面有一栏需要我们填写自己以后的梦想职业，我清楚记得我填的是机械学家。我记得小学的那段时光，无聊就喜欢拿螺丝刀拆开玩具，去看里面的结构。机械齿轮交互的结构多么优雅啊，所以我那时就问我妈，会做这些机械结构的职业叫什么？——“机械学家”。然后在那本册子上，我的梦想就是去成为机械学家。</p>
<p>后来我知道，我真正喜欢的是编程，是代码，是他们耦合交互时的紧密，是他们解耦设计时的优雅。我太喜欢“优雅”这个词了，elegant！</p>
<p>我初中学了基础的 C++ 知识，参加了可能有用的竞赛，玩了很多自托管的服务。高中时我磕磕绊绊做出了一个小程序，那是社团的一个气象小程序。我那时觉得，我以后大学毕业，一定会是一名程序员，一名优雅的软件开发程序员。每天，去实现一个新的 feature ，去修几个之前的 bugs，然后精细的分别写上 commit message，push remote。那时，我手边总会刚好有一杯拿铁或奶茶，惬意的就像初二时在严公子的阅读课上读书。</p>
<p>最近认识的阳同学，在高中也是这么想的。</p>
<hr>
<p>那现在呢，Java 开发岗怎么样呢？是程序员 35 岁优化的代名词吗？</p>
<p>“不对不对，那不过是平庸程序员的终章，我可是一位优雅的程序员。”</p>
<p>“是吗？.....”</p>
<hr>
<p>不过，严肃的来说，去了开发岗也并不会就一直在开发一线。一些话也只不过是大众的饭后笑料和凭空的焦虑罢了。</p>
<p>但我大概的确已经离软件开发渐行渐远了，就我现在的方向来看，确实应该不怎么会和高中时真正设想的程序员生活有什么交集。我没有什么写代码的硬实力，我喜欢用 cursor ，遇到什么问题就是先群发一遍 gpt claude 再说。更重要的是，或许我可能会从什么时候开始，会不会就放弃那种最纯粹的优雅了呢？配环境，跑项目，改项目，最近我所进行地很多项目活动，貌似都是只要能跑起来就行，因为并没有那么多时间去完善。以后工作了，会不会也一样被项目进度赶着完成？“跑通”是否就永远代替了“0 Warning(s) 0 error(s)”的优雅？</p>
<hr>
<p>但还好我还在上大学，一个常常被记忆烙印为乌托邦的时光。我还能去享受一下我期待的那种写代码的生活，我并没有真的被进度压到什么事情都放弃我骨子里的优雅气。想要做什么，想怎么做，那就怎么做就行了。多满足一点自己的心意。</p>
<hr>
<p>我真的很喜欢 PR 里的那一句简单的 lgtm ，紫色的 Merged 图标。那是我的优雅得到了别人认可的提现，也是我对自己认可的满足。</p>
<p><a href="https://github.com/Samueli924/chaoxing/commit/a3f58e9dfb5d4f2f57be7f500ff381ff7a60625c">https://github.com/Samueli924/chaoxing/commit/a3f58e9dfb5d4f2f57be7f500ff381ff7a60625c</a></p>
<p></p>
<p>My PR merged 10 minutes ago, where will the branch of my life be merged to?</p>

      <p style='text-align: right'>
      <a href='https://snowflake.pink/notes/11#comments'>看完了？说点什么呢</a>
      </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">67f2a5a50bb6d63f130088d7</guid>
  <category>notes</category>
false
 </item>
  <item>
    <title>使用 OpenWrt 软路由搭建一个低成本/单硬盘/增量备份的 Nextcloud</title>
    <link>https://snowflake.pink/posts/geek/nextcloud-with-openwrt</link>
    <pubDate>Tue, 18 Feb 2025 10:03:35 GMT</pubDate>
    <description>我在当年中考之后就了解到了 Nextcloud 这个开源的网盘，在自托管部署带来的丰盈成就感下，自己</description>
    <content:encoded><![CDATA[
      <blockquote>该渲染由 marked 生成，可能存在排版问题，最佳体验请前往：<a href='https://snowflake.pink/posts/geek/nextcloud-with-openwrt'>https://snowflake.pink/posts/geek/nextcloud-with-openwrt</a></blockquote>
      <p>我在当年中考之后就了解到了 Nextcloud 这个开源的网盘，在自托管部署带来的丰盈成就感下，自己仗着一台 HK 的小鸡和阿里云 SSO 的 10G 免费空间额度，便飘飘然尝试部署了一次 Nextcloud 。</p>
<p><a href="https://github.com/nextcloud/server">https://github.com/nextcloud/server</a></p>
<h1>初试 &amp; 背景</h1>
<p>好在当时我的专业天赋并没有拖文档 Google 翻译的后腿，还是能勉强地知道哪些命令是要 Copy 的，哪些命令是不能 Copy 的，最后搞出来的 Nextcloud 也算是能成功使用的。但是使用效果非常受限于服务器的可怜带宽和空间，当时的服务器带宽为 30M 独享，剩余可用空间大约为 20G ，整体下载速度也就 4Mb/s 左右。嗯🤔，突然想起来，当时是没有使用阿里云 SSO 来扩展可用空间的，因为 Nextcloud 使用外部存储的话（如果我没理解错），外部存储的文件也必须要走 Nextcloud 的服务器分发出去，无法直接从对象存储直链下载。所以如果使用外部存储的话，多少还是有点愚蠢了，一份文件的下载不仅受到服务器带宽的限制，其下载流量消耗也是双倍的，更不用说对象储存还存在一定的延迟性能之类的问题。除这些以外，对象储存还有高昂的空间和流量费用，唯一优势也就是不会丢数据了。</p>
<hr>
<h1>新的思路</h1>
<p>从部署背景来看，全部使用上云方案还是太吃经济了，那么有没有什么更加“简单”又经济的部署方案呢？<span class="spoiler" style="filter: invert(25%)">有的兄弟，有的
</span> 所以肯定是只能使用本地机器部署更加性价比了，刚好家里网络环境需求比较多样，正好需要买一个软路由。这样加个硬盘自建网盘也就刚好是顺手的事情了。</p>
<h1>部署过程</h1>
<h2>软路由</h2>
<p>软路由我选择购置还算挺新的 N100 平台（康耐信 4 x 2.5G 网口），毕竟需要安装的程序也算多，所以就上了 16G 内存 + 256 固态的系统配置，外加 SATA 4T 机械硬盘挂载。系统我就选择了 ImmortalWrt ，听说软件包源更丰富一点（似乎极限条件下的网络性能也会更好一点，但是我感觉绝大部分情况下并不会达到那种极限网络负载）。</p>
<p>在 OpenWrt 上我必须要吐槽一下，当时我是年前安装的系统，我看 24.10版本还属于  Release Candidate 的状态，想着 docker 部署应该用不上什么很新的特性，于是自然而然就选择上了 Stable 23.05 版本。但是直到我最后把网络完全配置好、Nginx 、DDNS 以及各种杂七杂八的环境配置好后，甚至是已经进行到 <code>docker compose up -d</code> 的最后一部 Nextcloud 部署了，<code>docker pull</code> 直接报错：</p>
<div class="container banner error"><p>docker: failed to register layer: lsetxattr security.capability /usr/bin/caddy: operation not supported.</p>
</div><p>最后，查到了相关的 PR 修复：</p>
<p><a href="https://github.com/openwrt/openwrt/pull/16181">https://github.com/openwrt/openwrt/pull/16181</a></p>
<p><a href="https://github.com/openwrt/openwrt/commit/2a1dd184b7d78d5c37a0c9a34b13ec69a4b16e04">https://github.com/openwrt/openwrt/commit/2a1dd184b7d78d5c37a0c9a34b13ec69a4b16e04</a></p>
<p>问题大概是 OpenWrt 在编译的时候精简了或没有启用一些特性，所以导致对 EXT4 文件系统的一些特性支持不善。该 PR 在 24 年 9 月 7 日被合并，并且应该已经在 10 月 2 日 v23.05.5 Release 中修复了这一问题。可惜的是，ImmortalWrt 并没有跟进 v23.05.5 的 OpenWrt 的版本。也就导致了我在年前刷到的“最新”版 ImmortalWrt 是由 v23.05.4 版本衍生而来的。非常小的一个 0.0.1 的版本更新，导致我不得不重刷软路由系统，所有配置一切重来。😭</p>
<p>虽然如此，在微信上和朋友分享抱怨了几句后，当晚就把系统刷到最新的 <a href="https://github.com/immortalwrt/immortalwrt/releases/tag/v24.10.0">ImmortalWrt v24.10.0</a> 版本了，第二次重新配置也不算很慢，当天从晚上 12 点一直配置到凌晨 4 点，差不多基本环境也还原到几个小时前的状态了。顺带一提，v24.10.0 版本还更新了核显驱动一类的支持，以前的 v23.x 版本如果需要使用 CPU 核显之类的话，只能自行编译。而有核显的好处，自然就是转码一类的操作可以硬解实现了，效率提升不止一点半点。</p>
<h2>其他基础配置</h2>
<p>由于我这边的电信宽带并没有开放 80 443 等常规端口，所以只能不太优雅地通过非常规端口访问家庭 Web 服务。配置好 Nginx 、 DDNS 、MySQL 等基本服务，基本 Web 能力就配置好了。</p>
<p>另外还要把硬盘分区和挂载搞定，固态硬盘似乎有留 10%~20% 剩余空间来延长固态寿命的说法，所以我就手动保持 20% 的空间处于未分配的状态（或者也可以空间全分配，然后自己保证存在剩余空间）。</p>
<p>机械硬盘方面，由于 MBR 分不了大于 2T 的分区，所以在分区的时候记得在 fdisk 中使用 GPT 分区（fdisk 默认为 MBR）。RAID 阵列方面，由于是低成本，并且 Nextcloud 可以自行配置 BorgBackups 增量备份，所以就直接使用单硬盘方案了。对个人来说，4T 硬盘只要不放影视资料，基本完全满足个人资料的放置和存储备份
需求。</p>
<h2>Nextcloud All in One</h2>
<p>然后终于到了 Nextcloud AIO 的部署环节。因为官方做测试的环境，是直接使用 443 端口这样的常规情况，然而当像大陆家庭网络环境下要使用特殊网络端口的话，部分默认配置可能就会出错。</p>
<h3>首次安装 AIO 容器</h3>
<p>本人使用 Docker Compose 部署，方便后续调整配置。</p>
<p>第一次部署容器前，一定要修改的就是 DATA_FOLDER 的环境变量，因为我们需要把数据存储在机械硬盘，而非固态硬盘。</p>
<p>还有个参数似乎叫 MNT_FOLDER ，用来挂载外部存储的硬盘。实际上，使用 SATA 挂载的机械硬盘不属于外部存储，因此该环境变量不必填写。</p>
<p>社区容器方面，可以按需添加一个 Jellyfin 和 Memories 转码容器。</p>
<p>PHP 拓展的环境变量注释也可以去掉，具体拓展名我忘了，但是用处是用来在线查看图片的，还是有必要加上。</p>
<p>KEEP_DISABLED_APP 可以选择修改为 True ，这个的作用等会一起说。</p>
<h3>首次启动 AIO 容器</h3>
<p>AIO 启动后，进入相关地址进行基本配置。注意 Nextcloud 域名访问地址的填写，像我这种使用特殊端口的，需要填写 <code>nextcloud.example.com:1111</code> 为域名，否则未来访问会出错。这个 1111 端口相当于是 Web 服务器的 443 端口，需要根据自己的 Web 服务器配置修改。</p>
<p>首次安装可以选择是否开启一些官方的功能支持容器，例如 ClamAV（检测病毒，但是可能导致破解版 exe 应用无法上传）、Collabora（在线 Office 功能）等，具体配置按需自行配置。其中，在使用单服务器域名+端口的部署环境下，我不太建议直接使用 AIO 配置的 Collabora 功能。具体原因会在下一部分讲述。</p>
<h3>Nextcloud Office （Collabora）配置</h3>
<p>Nextcloud AIO 自动配置的 Collabora 容器中，会把 Nextcloud 的域名地址设置为 <code>{NEXTCLOUD_DOMAIN}:443</code>，默认使用 443 端口配置的 Nextcloud 能被正确配置，但是在本文讨论的环境下（域名+非常规端口），会被设置为 <code>nextcloud.example.com:xxxx:443</code> ，从而导致 Collabora 容器无法正常运行。因此我们需要手动配置部署 Collabora 容器。</p>
<p>Nextcloud 实现在线 Office 功能，需要一个满足以下的通讯关系：（<a href="https://help.nextcloud.com/t/collabora-integration-guide/151879">官方论坛的指导</a>）</p>
<pre class="mermaid">graph LR
    client["Client"]
    Nextcloud["Nextcloud"]
    Collabora["Collabora"]
    
    client --> Nextcloud
    client --> Collabora
    Nextcloud --> Collabora
    Collabora --> Nextcloud
    </pre><p>可以看出 Client 需要能直接与 Collabora 服务通讯，而 Nextcloud 和 Collabora 之间也需要能直接服务通讯，并且他们通讯之间使用的域名无法改变（即 Client 访问 Nextcloud 必须通过 <code>https://nextcloud.example.com:xxx</code> ，Collabora 与 Nextcloud 通讯也必须通过 <code>https://nextcloud.example.com:xxx</code> 。</p>
<p>所以现在就出现了一个问题，即 Nextcloud 与 Collabora 都是使用 docker 容器在同一服务器进行部署的。然而容器内部的 DNS 会把 Nextcloud 和 Collabora 的域名全部解析为外部 IP 访问地址，但是容器内直接使用外部 IP 访问宿主机上的服务是无法进行通讯的。容器内访问另一容器的服务或者宿主机上的服务，只能通过 docker 容器内部 IP 地址才能进行通讯。因此我们调整容器内的 DNS 解析，来实现容器内的正确通讯。</p>
<p>具体配置仅需单独设置 Collabora 容器的 <code>docker-compose.yml</code> 配置，笔者样例配置如下：</p>
<pre><code class="language-yml">services:
  collabora:
    image: collabora/code
    container_name: collabora
    environment:
      - domain=nextcloud\.example\.com # Nextcloud 域名正则表达式（根据实际修改）
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true
      - server_name=your-collabora.example.com:xxxx # Collabora 域名（根据实际修改）
      - username=${USERNAME} # 在此配置USERNAME / PASSWORD 或在本 compose.yml 同目录创建 .env 文件储存该信息
      - password=${PASSWORD}
    cap_add:
      - MKNOD
    restart: unless-stopped
    networks:
      - nextcloud-aio
    extra_hosts:
      - "nextcloud.example.com:host-gateway" # 指向宿主机的 Nextcloud 反代服务，由于 Nextcloud 容器的内部 IP 会在每日备份后被重置而改变
                                                                                                       # 因此直接指向宿主机，使其与反代服务通讯更为合适 （根据实际修改域名）

# Nginx 反代
  nginx: 
    image: nginx:alpine
    container_name: collabora-nginx
    ports:
      - "xxxx:19080" # （根据实际修改）
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ../../nginx-proxy-manager/letsencrypt/live/npm-1/fullchain.pem:/etc/nginx/ssl/cert.crt # SSL 证书（根据实际修改）
      - ../../nginx-proxy-manager/letsencrypt/live/npm-1/privkey.pem:/etc/nginx/ssl/priv.key # SSL 证书（根据实际修改）
    depends_on:
      - collabora
    networks:
      nextcloud-aio:
        aliases:
          - your-collabora.example.com # 网络别名，让 Nextcloud 容器能 DNS 解析到 Collabora 容器地址
                                                                               # Nextcloud 容器为什么不也使用这个网络别名来实现正确解析？
                                                                               # 因为 Nextcloud 容器被 AIO 主容器配置部署，难以像 compose.yml 这样直接配置网络别名

networks:
  nextcloud-aio:
    external: true</code></pre><p>此外，我们需要在 Nextcloud AIO Master Container 的控制面板中关闭 Collabora 的自动部署选项，然后在 <code>docker-compose.yml</code> 设置 <code>NEXTCLOUD_KEEP_DISABLED_APPS: true</code> ，如果不把这个设置为 True，Nextcloud 会在每天备份后的容器重制过程中，卸载 Nextcloud Office 应用，因此导致每次重制后都要手动重新安装 Nextcloud Office 。</p>
<p>最后只需要使用管理员账户在 Nextcloud Office 配置中，把 Collabora 的服务器地址配置为 <code>https://your-collabora.example.com:xxxx</code> 即可。</p>
<h3>低成本的增量备份方案：BorgBackup</h3>
<p>既然我们使用了单 4T 硬盘进行 Nextcloud 的数据储存，那么一般来说我们基本上也至少要使用一个有 4T 大小的空间来进行备份。那么思来想去，低成本的方法只能想到 Onedrive 5T 账号来实现数据的备份了。同时，Nextcloud 本身也支持一个非常优雅的增量备份方案：BorgBackup。</p>
<p><a href="https://github.com/borgbackup/borg">https://github.com/borgbackup/borg</a></p>
<p>而 Borgbackup 主要增量备份思路为保存很多小的数据块元数据和大的压缩过后的数据块。真正备份的数据会被压缩保存为大块的数据块，然后每次增量备份进行时，仅需检索元数据（小文件）来计算新一次备份相比旧的所有备份数据需要备份的新数据。</p>
<p>未完待续......</p>

      <p style='text-align: right'>
      <a href='https://snowflake.pink/posts/geek/nextcloud-with-openwrt#comments'>看完了？说点什么呢</a>
      </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">67b45af70bb6d63f13fddb24</guid>
  <category>posts</category>
<category>Geek</category>
 </item>
  <item>
    <title>真•再会</title>
    <link>https://snowflake.pink/notes/9</link>
    <pubDate>Tue, 18 Feb 2025 08:52:37 GMT</pubDate>
    <description>提早几日回到了校园，现在距离上次写博文依然过去了XX天。最后一次赛博落笔的《再会》，实际想寄托的无非</description>
    <content:encoded><![CDATA[
      <blockquote>该渲染由 marked 生成，可能存在排版问题，最佳体验请前往：<a href='https://snowflake.pink/notes/9'>https://snowflake.pink/notes/9</a></blockquote>
      <p>提早几日回到了校园，现在距离上次写博文依然过去了XX天。最后一次赛博落笔的《再会》，实际想寄托的无非是想让自己依然重拾博文之趣，在高中依然能尽量坚持这样的乐趣。很可惜，由于各种各样的原因，最终还是没能坚持一点那时对高中生活的夙愿。于是，那篇《再会》也就变成了“再见”的代名词。</p>
<p>所以，这次我想以《真•再会》来作为这篇随笔的标题。再见——让我们再次见面！</p>
<p>这篇继续写什么呢？不知道，慢慢写吧，想到什么写什么，想写什么写什么。</p>

      <p style='text-align: right'>
      <a href='https://snowflake.pink/notes/9#comments'>看完了？说点什么呢</a>
      </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">67b44a550bb6d63f13fdd986</guid>
  <category>notes</category>
false
 </item>
  <item>
    <title>再会</title>
    <link>https://snowflake.pink/notes/1</link>
    <pubDate>Tue, 18 Aug 2020 14:31:00 GMT</pubDate>
    <description>由于初三学业繁忙，和一些其他各种各样的原因，我已经很久没有写过一篇完整的博客了。

记得去年10月份</description>
    <content:encoded><![CDATA[
      <blockquote>该渲染由 marked 生成，可能存在排版问题，最佳体验请前往：<a href='https://snowflake.pink/notes/1'>https://snowflake.pink/notes/1</a></blockquote>
      <p>由于初三学业繁忙，和一些其他各种各样的原因，我已经很久没有写过一篇完整的博客了。</p>
<p>记得去年10月份的时候还写过一篇《CSP 自勉》的博文，但是后面自己不爽删掉了，这算是我写的最新的一篇完整的博文了吧。这么久没更新，应该也没有多少人关注这个博客了。现在回看我收藏夹里的一些 <span class="katex-render">dalao</span> 的博客，比如 memset0，YuGao，wjyyy 这些 <span class="katex-render">dalao</span> 都没怎么更新博客了。顿时有一种网抑云的感觉冲上头来。</p>
<hr>
<p>至于最近考完的中考，应该差不多结束快一个月了<del>（不得不吐槽下，为什么我们这届初三只有一个月的假期）</del>，中考虽然意外挺多，但是结果还算满意，去的起码也是深圳的四大之一了<del>（差点搬砖）</del>。</p>
<p>打了两周的游戏后，决定还是要开始重新拾起这个博客，刚刚还去申请了下十年之约，希望我的这个小博客也能伴随我直到上完大学吧（QAQ）。前几天把博客的 <span class="katex-render">\KaTeX</span> 插件修好了，基本上可以正常的写博客了，希望我在深外也继续现役信息学吧（QwQ）。</p>
<hr>
<p>最近还因为之前的 iPhone 6 坏掉了，所以换了一个 K30 Pro<del>（然而后面就发布了 K30 Ultra）</del>，整体还是挺香的，希望不会买前生产力，买后爱奇艺（qwq）</p>
<hr>
<p>好，就酱~~</p>
<p>[Meting]
[Music title=&quot;千千阙歌&quot; author=&quot;陈慧娴&quot; url=&quot;<a href="https://cdn.snowflake.pink/music/%E5%8D%83%E5%8D%83%E9%98%99%E6%AD%8C/%E5%8D%83%E5%8D%83%E9%98%99%E6%AD%8C%20-%20%E9%99%88%E6%85%A7%E5%A8%B4.mp3">https://cdn.snowflake.pink/music/%E5%8D%83%E5%8D%83%E9%98%99%E6%AD%8C/%E5%8D%83%E5%8D%83%E9%98%99%E6%AD%8C%20-%20%E9%99%88%E6%85%A7%E5%A8%B4.mp3</a>&quot; pic=&quot;<a href="https://cdn.snowflake.pink/music/%E5%8D%83%E5%8D%83%E9%98%99%E6%AD%8C/%E5%8D%83%E5%8D%83%E9%98%99%E6%AD%8C.jpg%22/%5D">https://cdn.snowflake.pink/music/%E5%8D%83%E5%8D%83%E9%98%99%E6%AD%8C/%E5%8D%83%E5%8D%83%E9%98%99%E6%AD%8C.jpg&quot;/]</a>
[/Meting]</p>

      <p style='text-align: right'>
      <a href='https://snowflake.pink/notes/1#comments'>看完了？说点什么呢</a>
      </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">6793297389c9091c31e46bdf</guid>
  <category>notes</category>
false
 </item>
  <item>
    <title>SPFA算法深度探究</title>
    <link>https://snowflake.pink/posts/oi/SPFA</link>
    <pubDate>Mon, 23 Mar 2020 01:50:00 GMT</pubDate>
    <description>SPFA？？

图论里面有一个致命的东西，那就是负权边，现在我会的算法中能解决负边的只有$O(n^3</description>
    <content:encoded><![CDATA[
      <blockquote>该渲染由 marked 生成，可能存在排版问题，最佳体验请前往：<a href='https://snowflake.pink/posts/oi/SPFA'>https://snowflake.pink/posts/oi/SPFA</a></blockquote>
      <h5>SPFA？？</h5>
<p>图论里面有一个致命的东西，那就是<strong>负权边</strong>，现在我会的算法中能解决负边的只有<span class="katex-render">O(n^3)</span>的<span class="katex-render">Floyd</span>......<del>遇到负权边我们还是要向SPFA伸手</del></p>
<hr>
<p>↑↑正文分割线</p>
<ul>
<li>SPFA说的<del>牛逼</del>一点就是<span class="katex-render">(Shortest</span> <span class="katex-render">Path</span> <span class="katex-render">Faster</span> <span class="katex-render">Algorithm)</span>，说的谦虚（全球化）一点就是<strong>队列优化的<span class="katex-render">Bellman-Ford</span>算法</strong>。那么这个<span class="katex-render">Bellman-Ford</span>又是什么东西呢？？</li>
</ul>
<h4><span class="katex-render">Bellman-Ford</span>算法</h4>
<ul>
<li><p>我在<a href="https://www.17shou.vip/2019/01/23/%E9%AB%98%E4%B8%AD%E9%83%A8%E5%AF%92%E5%81%87%E9%9B%86%E8%AE%ADDay1/">寒假集训Day1</a>的笔记里曾提到这个东西，松弛：<span class="katex-render">dis[v]=\min⁡(dis[v],dis[u]+dis(u,v))</span></p>
<ul>
<li>核心代码：</li>
</ul>
<pre><code class="language-cpp">for (int k=1;k&lt;=n-1;k++)//n是顶点的数量
    for (itn i=1;i&lt;=m;i++)//m是边的数量
        if (dis[v[i]]&gt;dis[u[i]]+w[i])//u[i]和v[i]是边的两个顶点
            dis[v[i]]=dis[u[i]]+w[i];//w[i]是边的费用</code></pre><ul>
<li>分析：首先，为什么要进行<span class="katex-render">n-1</span>次呢？？因为在<span class="katex-render">n</span>个顶点的图中，任意两点的最短路最多包含<span class="katex-render">n-1</span>条边。这样算下来，时间复杂度是<span class="katex-render">O(nm)</span>，当然还可以优化（不是SPFA），可以发现我们常常在<span class="katex-render">n-1</span>次循环以前就完成了所有松弛，如果发现某次松弛没有发生变化，即可提前跳出循环。</li>
</ul>
</li>
</ul>
<!--more-->

<ul>
<li>判断负权边：进行<span class="katex-render">n-1</span>次松弛后再来一次松弛，如果答案还有变化，说明有负权边。</li>
</ul>
<h4><span class="katex-render">SPFA</span>算法</h4>
<ul>
<li>同上，我曾经在同一篇文章上写过，但是人的本质是复读机，所以.......</li>
<li>算法：每次选取队首顶点<span class="katex-render">u</span>，对顶点<span class="katex-render">u</span>的所有出边进行松弛。如果有一条<span class="katex-render">u</span>→<span class="katex-render">v</span>的边可以使源点到<span class="katex-render">v</span>的距离变短，就把<span class="katex-render">v</span>放加入队尾。<del>细心的你一定会发现</del>，同一个顶点在队列中出现多次是没有意义的，所以再开一个数组来判重就可以了。对顶点<span class="katex-render">u</span>的所有出边松弛完后，就让<span class="katex-render">u</span>出队。如此反复，知道队列空，<del>是不是很像<span class="katex-render">bfs</span>？？</del></li>
<li>Code：@codesonic dalao的模板</li>
</ul>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;queue&gt;
using namespace std;

const int inf=2147483647;
const int maxn=10005;
int n,m,b,e=0,i,j;
int dis[maxn],head[500005];
bool vis[maxn];
struct node
{
  int next,to,dis;
}edge[500005]; 

queue&lt;int&gt; q;
void addedge(int from,int to,int dis)
{
    edge[++e].next=head[from];
    edge[e].dis=dis;
    edge[e].to=to;
    head[from]=e;
}

void spfa()
{
    for(i=1;i&lt;=n;i++) dis[i]=inf;
    dis[b]=0;
    q.push(b),vis[b]=1;
    while(!q.empty())
    {
        int begin=q.front();
        q.pop(); 
        for(i=head[begin];i;i=edge[i].next)
        {
            if(dis[edge[i].to]&gt;dis[begin]+edge[i].dis)
            {
                dis[edge[i].to]=dis[begin]+edge[i].dis;
                if(!vis[edge[i].to]) 
                {
                    vis[edge[i].to]=1;
                    q.push(edge[i].to);
                }
            }
        }
        vis[begin]=0;
    }
}
int main()
{
    cin&gt;&gt;n&gt;&gt;m&gt;&gt;b;
    for(int i=1; i&lt;=m; i++)
    {
        int f,t,d;
        cin&gt;&gt;f&gt;&gt;t&gt;&gt;d; 
        addedge(f,t,d); 
    }
    spfa(); 
    for(int i=1; i&lt;=n; i++)
        if(b==i) cout&lt;&lt;0&lt;&lt;' '; 
        else cout&lt;&lt;dis[i]&lt;&lt;' ';
    return 0;
}</code></pre><ul>
<li>但是，众所周知，<span class="katex-render">SPFA</span>是会被毒瘤出题人卡的，最坏复杂度也是<span class="katex-render">O(nm)</span>，所以如果没有负权边的话，最好还是用<span class="katex-render">Dijkstra</span>，复杂度<span class="katex-render">O((M+N) \log N)</span>。</li>
</ul>
<h4>SPFA的其他优化</h4>
<p><del>咕咕咕......（等待更新QAQ）</del>更新分割线↓↓↓</p>
<hr>
<ul>
<li>上面提到过，原始的<span class="katex-render">SPFA</span>有<span class="katex-render">bfs</span>的思想，所以每次遇到负边的时候，复杂度就会降为<span class="katex-render">O(nm)</span>，所以针对这个问题，可以使用<span class="katex-render">dfs</span>版的<span class="katex-render">SPFA</span>，直接从新节点开始往下递归。判断负环也更为简单，如果存在<span class="katex-render">a_1 \Rightarrow a_2 \Rightarrow a_3 \Rightarrow .... \Rightarrow a_k \Rightarrow a_1</span>，那么就可以确定这是一个环，所以只要用一个数组来记录一个结点是否在递归栈中就可以了~~</li>
<li>伪代码：</li>
</ul>
<pre><code class="language-cpp">Void SPFA(Node){
    Instack[Node]=true;
    For (NOde,v) ∈ E
        If dis[Node]+edge(Node,v)&lt;dis[v] then{
            dis[v]=dis[Node]+edge(Node,v);
            If not Instack[v] then
                SPFA();
            Else
                Return;
        }
    Instack[Node]=false;
}</code></pre><h4>基于dfs的SPFA相关优化</h4>
<p>咕咕咕.....(等待更新)</p>

      <p style='text-align: right'>
      <a href='https://snowflake.pink/posts/oi/SPFA#comments'>看完了？说点什么呢</a>
      </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">67934ca12d340ea090fefafc</guid>
  <category>posts</category>
<category>信息学</category>
 </item>
  <item>
    <title>[已过时] 如何白嫖 UU</title>
    <link>https://snowflake.pink/posts/strange/free-UU</link>
    <pubDate>Thu, 19 Mar 2020 07:46:00 GMT</pubDate>
    <description>一时白嫖一时爽，一直白嫖......   

早就想写这篇文章了，但是感觉在博客里面发出来怪怪的 q</description>
    <content:encoded><![CDATA[
      <blockquote>该渲染由 marked 生成，可能存在排版问题，最佳体验请前往：<a href='https://snowflake.pink/posts/strange/free-UU'>https://snowflake.pink/posts/strange/free-UU</a></blockquote>
      <p>一时白嫖一时爽，一直白嫖......   </p>
<hr>
<p>早就想写这篇文章了，但是感觉在博客里面发出来怪怪的 qwq</p>
<h2>原理</h2>
<p>用过 UU 的人如果想去白嫖，那么一定会产生一个非常简单的想法。那就是让 UU 觉得这是一台没有用过 UU 的电脑。所以虚拟修改一下电脑的一些信息就可以了。（是不是很简单？QAQ）</p>
<h2>准备软件</h2>
<p>这个修改器的破解版差不多已经绝版了，这是我自己收藏的，发出来。</p>
<ul>
<li><a href="https://cdn.17shou.vip/hardware.exe">修改器</a></li>
<li>UU：这个自己去官网下</li>
</ul>
<h2>白嫖</h2>
<p>首先你要有手机号，如果自己手机号多够用就不用这一步了。</p>
<p>这个时候就需要找到一个接码平台，上面的手机号是取之不尽的，价钱大概几毛钱一条短信。</p>
<p>然后使用管理员权限启动 <code>hardware.exe</code> ，然后如图操作：</p>
<p></p>
<p>最后点击启动，进入 UU 的目录启动 <code>uu.exe</code> 即可。</p>
<p>然后使用手机号（接码平台）登陆，会有 3 天试用，实现白嫖的目的。</p>
<h2>注意事项</h2>
<ul>
<li><p>后面启动 UU 时候，需要在 <code>hardware.exe</code> 中填写以前随机后的序列号和 MAC 地址，试用期完后要再次随机。</p>
</li>
<li><p>启动 UU 后可以关闭 <code>hardware.exe</code> 。</p>
</li>
<li><p>记得使用管理员权限运行。</p>
</li>
</ul>
<h2>参考资料</h2>
<ul>
<li><a href="https://www.52pojie.cn/thread-970642-1-1.html">吾爱破解</a></li>
</ul>

      <p style='text-align: right'>
      <a href='https://snowflake.pink/posts/strange/free-UU#comments'>看完了？说点什么呢</a>
      </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">67934c5a2d340ea090fefad1</guid>
  <category>posts</category>
<category>爱玩</category>
 </item>
  <item>
    <title>2019.8.15 集训解题报告</title>
    <link>https://snowflake.pink/posts/oi/training19-08-15</link>
    <pubDate>Thu, 15 Aug 2019 14:26:00 GMT</pubDate>
    <description>今天好像考数学......

笔记

矩阵

今天好像考数学，但是我太菜了，就不想考了.....

</description>
    <content:encoded><![CDATA[
      <blockquote>该渲染由 marked 生成，可能存在排版问题，最佳体验请前往：<a href='https://snowflake.pink/posts/oi/training19-08-15'>https://snowflake.pink/posts/oi/training19-08-15</a></blockquote>
      <p>今天好像考数学......</p>
<hr>
<h1>笔记</h1>
<h2>矩阵</h2>
<p>今天好像考数学，但是我太菜了，就不想考了.....</p>
<p>然后就用这个时间来补数学 qwq</p>
<h4>普通递推数列</h4>
<h6>题面</h6>
<p>给出一个 <span class="katex-render">k</span> 阶齐次递推数列 <span class="katex-render">\{f_i \}</span> 的通项公式 <span class="katex-render">f_i = a_1 \times f_{i - 1} + a_2 \times f_{i - 2} + ... +a_k \times f_{i - k}(i \geq k)</span> ，求 <span class="katex-render">f_n</span> 。</p>
<h6>分析</h6>
<p>这和上次考试的 “小 L 的数列” 有点像，但是还是差了很多。</p>
<p>令：
<span class="katex-render">$
F = \begin{bmatrix} f_{i - 1} \\ f_{i - 2} \\ \vdots \\ f_{i - k}\end{bmatrix},F' = \begin{bmatrix} f_i \\ f_{i - 1} \\ \vdots \\ f_{i - k + 1}\end{bmatrix}
$</span>
然后 <strong>通过比较</strong> （数学一本通上的话相当精辟），得出一个矩阵 <span class="katex-render">A</span> ，使得 <span class="katex-render">F' = A \times F</span>：
<span class="katex-render">$
A = \begin{bmatrix} a_1 & a_2 & a_3 & \cdots & a_k \\ 1 & 0 & 0 & \cdots & 0 \\ 0 & 1 & 0 & \cdots & 0 \\\vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & 1 & 0\end{bmatrix}
$</span>
然后就有：
<span class="katex-render">$
F_i = A^i \times F_0 = \begin{bmatrix} f_{i + k - 1} \\ f_{i + k - 2} \\ \vdots \\ f_i \end{bmatrix}
$</span></p>
<hr>
<p>怎么推出这个矩阵的啊 QAQ</p>
<p>有一个算法叫做 <span class="katex-render">Strassen</span> 算法，可以把这题的复杂度从 <span class="katex-render">O(k^3 \log_2 n)</span> 降到 <span class="katex-render">O(k^{2.81} log_2 n)</span> ？！</p>
<p>玄学复杂度.....</p>
<p>我也不会去学的......</p>
<h1>考试</h1>
<p>今天的第一题竟然水得一逼......</p>
<h2>库特的向量</h2>
<p>直接贪心....</p>
<p>一个从小到大排序，另一个从大到小排序，然后依次对应的取他们的积 QAQ</p>
<p><span class="katex-render">Fixed</span> <span class="katex-render">Code</span>：100%</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdio&gt;
#include &lt;algorithm&gt;

using namespace std;
const int MAXN = 1e3 + 5;

long long n, a[MAXN], b[MAXN], ans;

bool cmp (long long a, long long b) {
	return a &gt; b;
}

int main() {
	scanf ("%lld", &n);
	for (int i = 1; i &lt;= n; i++) {
		scanf ("%lld", &a[i]);
	}
	for (int i = 1; i &lt;= n; i++) {
		scanf ("%lld", &b[i]);
	}
	
	sort (a + 1, a + n + 1);
	sort (b + 1, b + n + 1, cmp);
	
	for (int i = 1; i &lt;= n; i++) {
		ans += a[i] * b[i];
	}
	
	printf ("%lld\n", ans);
	return 0;
}</code></pre><h2>恭介的法则</h2>
<p>一道数学题，题目要求，在正整数集合中，有多少对 <span class="katex-render">(x,y)</span> 使得 <span class="katex-render">\frac{1}{x} + \frac{1}{y} = \frac{1}{n!}</span> 。</p>
<p>推导过程：
<span class="katex-render">$
\begin{aligned}
\frac{1}{x} + \frac{1}{y} &= \frac{1}{n!} \\
\frac{x + y}{xy} &= \frac{1}{n!} \\ 
xy &= x \cdot n! + y \cdot n! \\
y &= \frac{x \cdot n!}{x - n!} \\
\end{aligned}
$</span>
因为，
<span class="katex-render">$
x,y,n! > 0
$</span>
所以，
<span class="katex-render">$
x - n! > 0
$</span>
令,
<span class="katex-render">$
x = n! + a(a>0)
$</span>
则，
<span class="katex-render">$
\begin{aligned}
y &= \frac{(n!)^2 + a \cdot n!}{a} \\
y &= n! + \frac{(n!)^2}{a}
\end{aligned}
$</span>
然后问题就转化为：在 <span class="katex-render">(n!)^2</span> 有多少个正整数因子，所以分解一下质因数，然后各个指数 <span class="katex-render">+</span> 1 乘起来的积即为答案。</p>

      <p style='text-align: right'>
      <a href='https://snowflake.pink/posts/oi/training19-08-15#comments'>看完了？说点什么呢</a>
      </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">67934bfa2d340ea090fefa9f</guid>
  <category>posts</category>
<category>信息学</category>
 </item>
  <item>
    <title>2019.8.13 集训解题报告</title>
    <link>https://snowflake.pink/posts/oi/training19-08-13</link>
    <pubDate>Tue, 13 Aug 2019 14:12:00 GMT</pubDate>
    <description>为什么我觉得今天的题这么水，恐怕要被打脸 qwq，是不是我题读错了....

考试

rank

题</description>
    <content:encoded><![CDATA[
      <blockquote>该渲染由 marked 生成，可能存在排版问题，最佳体验请前往：<a href='https://snowflake.pink/posts/oi/training19-08-13'>https://snowflake.pink/posts/oi/training19-08-13</a></blockquote>
      <p><del>为什么我觉得今天的题这么水</del>，恐怕要被打脸 qwq，是不是我题读错了....</p>
<hr>
<h1>考试</h1>
<h2>rank</h2>
<p>题意有点问题，我赌输出 <span class="katex-render">k</span> 个答案是对的 qwq</p>
<hr>
<p>JZOJ 评测吃了我 50 分</p>
<p><span class="katex-render">Test's</span> <span class="katex-render">Code</span>：100%</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdio&gt;
#include &lt;algorithm&gt;

using namespace std;
const int MAXN = 5e6 + 5;
const int MAXM = 1e5 + 5;

int n, a[MAXN], k;
int main() {
	scanf ("%d%d", &n, &k);
	for (int i = 1; i &lt;= n; i++) {
		scanf ("%d", &a[i]);
	}
	
	sort (a + 1, a + n + 1);
	
	for (int i = 1; i &lt;= k; i++) {
		printf ("%d ", a[i]);
	}
	return 0;
}</code></pre><h2>seek</h2>
<p>考试的时候用 <span class="katex-render">KMP</span> 生成 <code>next[i]</code> 数组的方式，再加了一个检测，这样瞎搞了以后应该是 0 分吧 qwq</p>
<hr>
<p>瞎搞搞了 20 分 qwq</p>
<p>好像暴力也有 40 分，早知道分段写了 qwq，说不定可以 60 分 &gt; _ &lt;</p>
<hr>
<p>上面是闲话：<span class="katex-render">\Uparrow \Uparrow</span></p>
<p>这道题有两种方法，第一种就是 <span class="katex-render">KMP</span> ，但是用来做这种变形我不会 qwq，我到现在只会生成普通的 <code>next[i]</code> ....</p>
<p>第二种是直接生成前缀、后缀哈希，然后再枚举一遍，扫 3 遍就可以了 qwq</p>
<p>我就喜欢像第二种这种简单粗暴的方法......</p>
<p><span class="katex-render">Test's</span> <span class="katex-render">Code</span>：20%</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdio&gt;
#include &lt;cstring&gt;

using namespace std;
const int MAXN = 4e5 + 5;

char ch[MAXN], len, kmp[MAXN];

bool book[MAXN];

int main() {
	scanf ("%s", ch);
	len = strlen (ch);
	
	int k=0;
	for(int i = 1; i &lt; len; i++){
		
		if (k && ch[i] != ch[k]) {
			bool flag = true;
			for (int j = 0; j &lt; k; j++) {
				if (ch[j] != ch[len - k + j]) {
					flag = false;
					break;
				}
			}
			if (flag) {
				book[k] = true;
			}
		}
		
    	while(k && ch[i] != ch[k])
        	k = kmp[k];
    	if(ch[i] == ch[k]) {
    		kmp[i + 1] = ++k;
    	}
	}
	
	bool flag = true;
	for (int j = 0; j &lt; k; j++) {
		if (ch[j] != ch[len - k + j]) {
			flag = false;
			break;
		}
	}
	if (flag) {
		book[k] = true;
	}
	
	//book[k] = true;
	book[len] = true;
	
	for (int i = 1; i &lt;= len; i++) {
		if (book[i]) {
			printf ("%d ", i);
		}
	}
	return 0;
}</code></pre><p><span class="katex-render">Fixed</span> <span class="katex-render">Code</span>：100%（哈希）</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdio&gt;
#include &lt;cstring&gt;

using namespace std;
const int MAXN = 4e5 + 5;

unsigned long long len, lhash[MAXN], rhash[MAXN];

char ch[MAXN];

int main() {
	scanf ("%s", ch + 1);
	len = strlen (ch + 1);
	
	for (int i = 1; i &lt;= len; i++) {
		lhash[i] = (lhash[i - 1] * 17 + ch[i] - 'a' + 1);
	}
	unsigned long long t = 1;
	for (int i = len; i &gt;= 1; i--) {
		rhash[i] = ((ch[i] - 'a' + 1) * t + rhash[i + 1]);
		t = t * 17;
	}
	
	for (int i = 1; i &lt;= len; i++) {
		if (lhash[i] == rhash[len - i + 1]) {
			printf ("%d ", i);
		}
	}
	return 0;
}</code></pre><p>这题有一些细节，就是进行哈希加密的时候，需要选质数，不然可能会有问题.......</p>
<p>这题不知道为什么我取模之后会出错，可能哈希就是不能取模吧......</p>
<p>可能因为我太菜了.....</p>
<h2>pot</h2>
<p>打了一个线段树，但是没有打完，最后因为答案要求不能全取，然后我就一直想怎么用 <span class="katex-render">O(\log n)</span> 的方法搜出答案 qwq</p>
<p>这题用线段树维护 最大字段和 和 最小子段和 就可以了。因为不能取一整个环，所以最后答案在 <span class="katex-render">(1,n]</span> 和 <span class="katex-render">[1,n)</span> 这两个区间中取一个 <span class="katex-render">Max</span> 就可以了。对于这个最长子段和，@lzc 是这么求的，直接引用了。。。（不会侵权吧。。。）</p>
<blockquote>
<p>在线段树每个结点上维护这个区间的和、最大前缀和、最大后缀和、最大子段和。
那么合并儿子信息的时候，区间和很简单；最大前缀和有两种选择，一种是左儿子的区间和 + 右儿子的最大前缀和，一种是左儿子的最大前缀和；后缀和类似；最大子段和要么是左儿子的最大子段和，要么是右儿子的最大子段和，要么是左儿子的最大后缀和 + 右儿子的最大前缀和。</p>
<p>—— lzc</p>
</blockquote>
<p>嗯，就酱紫吧？</p>
<p><span class="katex-render">Test's</span> <span class="katex-render">Code</span>：0%</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdio&gt;

using namespace std;
const int MAXN = 1e5 + 5;
const int MAXM = 1e5 + 5;
const int INF = 2e9;
int n, m, rt, a[MAXN &lt;&lt; 1];

struct Tree {
	#define lson (x &lt;&lt; 1)
	#define rson (x &lt;&lt; 1) + 1
	int size[MAXN &lt;&lt; 2], Max[MAXN &lt;&lt; 2], num[MAXN &lt;&lt; 2], sum[MAXN &lt;&lt; 2];
	
	inline void pushup_normal (int x) {
		size[x] = size[lson] + size[rson];
		sum[x] = sum[lson] + sum[rson];
		Max[x] = max (Max[lson], Max[rson]);
		Max[x] = max (Max[x], sum[x]);
		return;
	}
	
	inline void pushup_ans (int x) {
		size[x] = size[lson] + size[rson];
		Max[x] = max (Max[lson], Max[rson]);
		return;
	}
	
	void insert (int x, int l, int r) {
		if (l == r) {
			size[x] = 1;
			sum[x] = 1;
			return;
		}
		int mid = (l + r) &gt;&gt; 1;
		insert (lson, l, mid);
		insert (rson, mid, r);
		if (r - l + 1 &gt; n) {
			pushup_ans (x);
		}
		
		else {
			pushup_normal (x);
		}
		return;
	}
	
	void Change (int x, int l, int r, int k, int val) {
		if (l == r) {
			Max[x] = val;
			sum[x] = val;
			return;
		}
		
		int mid = (l + r) &gt;&gt; 1;
		if (mid &lt; k) {
			Change (rson, mid, r, k, val);
		}
		else {
			Change (lson, l, mid, k, val);
		}
		pushup_normal (x);
		return;
	}
	
};
Tree T;

int main() {
	scanf ("%d", &n);
	for (int i = 1; i &lt;= n; i++) {
		scanf ("%d", &a[i]);
		a[n + i] = a[i];
	}
	T.insert (rt, 1, 2 * n);
	
	scanf ("%d", &m);
	for (int i = 1; i &lt;= m; i++) {
		int k, val;
		scanf ("%d%d", &k, &val);
		T.Change (rt, 1, 2 * n, k, val);
		T.Change (rt, 1, 2 * n, n + k, val);
		int MAX = -INF;
		for (int i = 1; i &lt;= n; i++) {
			MAX = max (MAX, T.query (rt, 1, 2 * n, i, n + i - 2));
		}
		printf ("%d\n", MAX);
	}
	return 0;
}</code></pre><p><span class="katex-render">Fixed</span> <span class="katex-render">Code</span>：</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdio&gt;

using namespace std;
const int MAXN = 1e5 + 5;

struct Tree {
	#define lson (x &lt;&lt; 1)
	#define rson (x &lt;&lt; 1) + 1
	int presum_Max[MAXN &lt;&lt; 2], sufsum_Max[MAXN &lt;&lt; 2], Max[MAXN &lt;&lt; 2];
	int presum_Min[MAXN &lt;&lt; 2], sufsum_Min[MAXN &lt;&lt; 2], Min[MAXN &lt;&lt; 2];
	int sum[MAXN &lt;&lt; 2], Min_val[MAXN &lt;&lt; 2], rt;
	
	inline void pushup (int x) {
		presum_Max[x] = max (presum_Max[lson], sum[lson] + presum_Max[rson]);
		sufsum_Max[x] = max (sufsum_Max[rson], sufsum_Max[lson] + sum[rson]);
		presum_Min[x] = min (presum_Min[lson], sum[lson] + presum_Min[rson]);
		sufsum_Min[x] = min (sufsum_Min[rson], sufsum_Min[lson] + sum[rson]);
		sum[x] = sum[lson] + sum[rson];
		Max[x] = max (Max[lson], Max[rson]);
		Max[x] = max (Max[x], sufsum_Max[lson] + presum_Max[rson]);
		Min[x] = min (Min[lson], Min[rson]);
		Min[x] = min (Min[x], sufsum_Min[lson] + presum_Min[rson]);
		Min_val[x] = min (Min_val[lson], Min_val[rson]);
		return;
	}
	
	void insert (int x, int l, int r) {
		if (l == r) {
			scanf ("%d", &sum[x]);
			presum_Max[x] = sum[x];
			sufsum_Max[x] = sum[x];
			presum_Min[x] = sum[x];
			sufsum_Min[x] = sum[x];
			Max[x] = sum[x];
			Min[x] = sum[x];
			Min_val[x] = sum[x];
			return;
		}
		int mid = (l + r) &gt;&gt; 1;
		insert (lson, l, mid);
		insert (rson, mid + 1, r);
		pushup(x);
		return;
	}
	
	void change (int x, int l, int r, int k, int val) {
		if (l == r) {
			sum[x] = val;
			presum_Max[x] = val;
			sufsum_Max[x] = val;
			presum_Min[x] = val;
			sufsum_Min[x] = val;
			Max[x] = val;
			Min[x] = val;
			Min_val[x] = val;
			return;
		}
		int mid = (l + r) &gt;&gt; 1;
		if (k &gt; mid) {
			change (rson, mid + 1, r, k, val);
		}
		else {
			change (lson, l, mid, k, val);
		}
		pushup(x);
		return;
	}
};
Tree T;

int n, m;
int main() {
	scanf ("%d", &n);
	T.rt = 1;
	T.insert (T.rt, 1, n);
	
	scanf ("%d", &m);
	for (int i = 1; i &lt;= m; i++) {
		int k, val;
		scanf ("%d%d", &k, &val);
		T.change (T.rt, 1, n, k, val);
		int temp;
		if (T.sum[T.rt] != T.Max[T.rt]) {
			temp = T.Max[T.rt];
		}
		else {
			temp = T.sum[T.rt] - T.Min_val[T.rt];
		}
		printf ("%d\n", max (temp, T.sum[T.rt] - T.Min[T.rt]));
	}
	return 0;
}</code></pre><p>这题改了很久，有一点，需要注意。因为不能取全部，所以如果最后有两种情况：</p>
<ul>
<li>最长子段和 <span class="katex-render">=</span> 总和：答案有两种情况取 <span class="katex-render">Max</span> ：总和 <span class="katex-render">-</span> 最小的单点值；总和 <span class="katex-render">-</span> 最小子段和。</li>
<li>最长子段和 <span class="katex-render">\not=</span> 总和：答案有两种情况取 <span class="katex-render">Max</span> ：最长子段和；总和 <span class="katex-render">-</span> 最小子段和（最长子段和的区间和最小子段和的区间可能在环的交界处）</li>
</ul>
<h2>游戏节目(show)</h2>
<p>算了一下，<span class="katex-render">C_{34}^{17} \approx 5 \times 10^7</span>，如果剪枝可以的话，应该可以卡过 qwq（这是我考试后口胡的，不用管）</p>
<p>为什么只有 40 分鸭 qwq，成功翻车......</p>
<hr>
<p>这道题远没有我考试时想的那么简单....</p>
<p>好像说要用什么树套树，折半搜索......信息量有点大，以后再订这道题.....</p>
<p><span class="katex-render">Test's</span> <span class="katex-render">Code</span>：40%</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdio&gt;

using namespace std;
const int MAXN = 40;
const int MAXK = 7;

long long n, k, ans, a[MAXN], b[MAXN], c[MAXN];
long long A, B, C;

void dfs (int now, int K, int last, int cnt) {
	if (now &gt;= cnt) {
		if (A &gt; B && A &gt; C) {
			ans ++;
		}
		return;
	}
	
	for (int i = last + 1; i &lt;= n - K + 1; i++) {
		A += a[i];
		B += b[i];
		C += c[i];
		dfs (now + 1, K - 1, i, cnt);
		A -= a[i];
		B -= b[i];
		C -= c[i];
	}
	return;
}
int main () {
	freopen ("show.in", "r", stdin);
	freopen ("show.out", "w", stdout);
	
	scanf ("%lld%lld", &n, &k);
	for (int i = 1; i &lt;= n; i++) {
		scanf ("%lld", &a[i]);
	}
	for (int i = 1; i &lt;= n; i++) {
		scanf ("%lld", &b[i]);
	}
	for (int i = 1; i &lt;= n; i++) {
		scanf ("%lld", &c[i]);
	}
	
	for (int i = k; i &lt;= n; i++) {
		dfs (0, i, 0, i);
	}
	
	printf ("%lld\n", ans);
	fclose (stdin);
	fclose (stdout);
	return 0;
}</code></pre>
      <p style='text-align: right'>
      <a href='https://snowflake.pink/posts/oi/training19-08-13#comments'>看完了？说点什么呢</a>
      </p>
    ]]>
    </content:encoded>
  <guid isPermaLink="false">67934bc92d340ea090fefa88</guid>
  <category>posts</category>
<category>信息学</category>
 </item>
  
</channel>
</rss>