整数溢出与未定义行为

在做 CSAPP Data Lab 的时候,关于整数溢出,遇到一些问题。 题干 1 2 3 4 5 6 7 8 9 10 11 /*  * isTmax - returns 1 if x is the maximum, two's complement number,  *     and 0 otherwise   *   Legal ops: ! ~ & ^ | +  *   Max ops: 10  *   Rating: 1  */ int isTmax(int x) {   return 2; } 题目要求,仅仅使用运算符 ! ~ & ^ | + 来判断一个数是否是最大的二的补码(int 范围内),即 0x7fffffff。如果是,输出 1;否则,输出 0。 思路 由于我们不能使用移位操作(很多人会直接 1<<31 - 1),可以考虑整数溢出的特殊性质。 具体地,我们有 0x7fffffff + 1 = 0x80000000,符号改变。 而 0x80000000 + 0x80000000 = 0 我们可以得到 x = 0x7fffffff 满足 x + 1 + x + 1 = 0 而对于其他数字,假设 y = x + k 其中 k 非零,则有 y + 1 + y + 1 = 2*k 此时,我们发现,对于 y=-1 也有 y + 1 + y + 1 = 0,需要排除掉 其他情况下,非零数转换为 bool 类型自动变为 1 我们不难写出以下代码: 1 2 3 4 5 int isTmax(int x) {   int p1 = x+1;   int p2 = p1 + p1;   return !(p2) & !!(p1); } 发现问题 这段代码在我本地(macOS,Apple clang version 17.0.0 (clang-1700.3.19.1), Target: arm64-apple-darwin25.0.0) 上运行,使用命令 clang main.c 是没有任何问题的。 但是,检查到 CSAPP 提供的 Makefile,有 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # # Makefile that builds btest and other helper programs for the CS:APP data lab # CC = gcc CFLAGS = -O -Wall LIBS = -lm all: btest fshow ishow btest: btest.c bits.c decl.c tests.c btest.h bits.h $(CC) $(CFLAGS) $(LIBS) -o btest bits.c btest.c decl.c tests.c fshow: fshow.c $(CC) $(CFLAGS) -o fshow fshow.c ishow: ishow.c $(CC) $(CFLAGS) -o ishow ishow.c # Forces a recompile. Used by the driver program. btestexplicit: $(CC) $(CFLAGS) $(LIBS) -o btest bits.c btest.c decl.c tests.c clean: rm -f *.o btest fshow ishow *~ 注意到,编译器使用了 -O flag,即 O1 优化。 此时执行这段代码,对于 0x7fffffff 输出 0,怀疑可能是编译器优化时,假设未定义行为(整数溢出)不会发生,将 !p2 优化。p1 + p1 的形式过于简单。 未定义行为 未定义行为(UB),根据 cppreference 的定义: 1 undefined behavior - There are no restrictions on the behavior of the program. 有符号整数溢出是一种常见的未定义行为。 Because correct C++ programs are free of undefined behavior, compilers may produce unexpected results when a program that actually has UB is compiled with optimization enabled. 也就是说,编译器优化会对未定义行为产生意料之外的结果 cppreference 给出了一个整数溢出的例子: 1 2 3 4 5 int foo(int x) { return x + 1 > x; // either true or UB due to signed overflow } 编译之后却变成了 1 2 3 foo(int): mov eax, 1 ret 意思是,不管怎么样都输出 1 观察出错代码 我们通过 gcc -S 输出编译后的汇编代码 1 2 3 4 5 6 7 _Z6isTmaxi: .LFB2: .cfi_startproc endbr64 movl$0, %eax ret .cfi_endproc 我们看到,编译器直接把这个函数返回值改成了 0,不管输入什么,与我们的错误原因推断是相同的。 修改 我们可以尝试构造一个更复杂的、不易被简单规则匹配的表达式,躲过 O1 级别的优化。 核心思路不变,仍然是利用 Tmax + 1 = Tmin 这个特性。我们来观察一下 Tmax 和 Tmin 在二进制下的关系: Tmax = 0x7fffffff = 0111...1111 Tmin = 0x80000000 = 1000...0000 一个非常有趣的性质是 Tmax + Tmin = -1 (0xffffffff)。 1 2 3 4 0111 1111 ... 1111 (Tmax) + 1000 0000 ... 0000 (Tmin) ------------------------- 1111 1111 ... 1111 (-1) 基于这个观察,我们可以设计一个新的检查方案:如果一个数 x 是 Tmax,那么 x + (x+1) 的结果就应该是 -1。取反后 ~(-1) 则为 0。 我们可以写出如下的修改版代码: 1 2 3 4 5 int isTmax(int x) { int map = x + 1; int res = ~(map + x); return !res & (!!map); } 这段代码的逻辑是: 计算 map = x + 1。对于 x = Tmax,这里同样会发生有符号溢出,map 变为 Tmin。这依然是未定义行为(UB)。 计算 res = ~(map + x)。如果 x 是 Tmax,这一步就是 ~(Tmin + Tmax),结果为 ~(-1),即 0。 return !res & (!!map)。!res 为 !0,即 1。!!map 部分和之前的版本一样,是为了排除 x = -1 的情况(此时 map 为 0, !!map 为 0,最终返回 0)。 这段代码在 -O 优化下可能会得到正确的结果。 为什么这个“可能”有效? 我们必须清醒地认识到,新版本的代码本质上没有解决未定义行为的问题,它只是“侥幸”地绕过了当前编译器版本的特定优化策略。 代码模式的复杂性:p1 + p1 ((x+1)+(x+1)) 是一个非常简单直白的模式,优化器很容易建立一个“如果 p1 非零,则 p1+p1 结果也非零”的优化规则。而 ~((x+1)+x) 混合了加法和位运算,模式更复杂,可能没有触发编译器中已有的、基于UB的优化捷径。 优化的机会主义:编译器优化并不是要穷尽所有的数学可能,而是应用一系列已知的高效模式。我们的新代码恰好不在这些常见模式的“黑名单”上。 所以,这个修改版只是一个更具迷惑性的“伪装”。它在特定环境下能工作,但其行为是不被C语言标准所保证的,在不同的编译器或未来的GCC版本下,它随时可能失效。 结论:如何正确面对未定义行为 通过 isTmax 这个小小的函数,我们可以一窥C语言中未定义行为的危险性以及现代编译器优化的强大。作为开发者,我们应该得到以下启示: 不要依赖未定义行为:永远不要编写依赖于UB的代码,即使它“在你的机器上看起来能跑”。代码的健壮性来源于对语言标准的严格遵守,而非侥幸。 相信编译器,但要验证:编译器非常聪明,它会严格按照语言规范进行优化。当你发现优化后的代码行为不符合你的“直觉”时,首先应该怀疑自己的代码是否触碰了UB的红线。 善用工具: 始终开启编译器警告 (-Wall -Wextra) 并将警告视为错误 (-Werror),这能帮你发现许多潜在问题。 使用运行时检测工具,如GCC/Clang的 UndefinedBehaviorSanitizer (UBSan)。只需在编译时加上 -fsanitize=undefined,它就能在程序运行时精确地捕获有符号整数溢出等UB,是调试这类问题的神器。 对于CSAPP Data Lab这道题来说,它的目的正是为了让我们在“规则的镣铐”下舞蹈,从而深刻理解整数表示、运算和编译器行为。而我们在实际工程中,最安全、最清晰的写法永远是第一选择。

2025/10/13
articleCard.readMore

快速排序 几种划分方法讨论

最近在复习数据结构与算法,聊聊快速排序的几种划分算法。 快速排序思路 快速排序是一种基于分治策略的排序算法。 对于待排序数组,其核心操作是: 选取一个基准数pivot 将数组分为两块,一块小于等于基准数,另一块大于等于基准数(注意 基准数作为分界点) 递归地对于分出来的两个数字再次进行快速排序 不断地进行划分,递归,最后能保证整个数组有序。 基准数的选取 一般来说,基准数有几种选取方法: 选取第一个数或者最后一个数:这样做,如果数组已经排好序,则每次划分都是基准数和剩余数,时间复杂度升至O(n^2) 随机选择一个数 选取中位数:这样做始终能对原数组进行等分,寻找中位数是线性时间的。 下面以最无脑的方法1为例。 几种划分方法 主要的划分方法有: 朴素划分 Lomuto 划分 Hoare 划分 中国大陆教材中经常出现的是第三种,即 Hoare 划分,也叫哨兵划分。 朴素划分 思路很无脑。直接开一个新数组,把比 pivot 小的放左边,比 pivot 大的放右边,最后把数组拷贝回到原数组。需要 O(n) 的额外空间。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const int N; // 数组长度 int A[N]; int tmp[N]; int Native_Partition(int left, int right) { int pivot = A[left]; int idx = left; for (int i = left; i <= right; i++) { if (A[i] < pivot) tmp[idx++] = A[i]; } // 先将小于等于 pivot 的复制进入 int pid = idx; tmp[idx++] = pivot; for (int i = left; i <= right; i++) { if (A[i] > pivot) tmp[idx++] = A[i]; } // 再将大于 pivot 的复制进入 for (int i = left; i <= right; i++) { A[i] = tmp[i]; } // 复制回到 A return pid; } Lomuto 划分 Lomuto 划分即使用单个指针,从左到右扫描数组,交换,维持划分顺序。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int Lomuto_Partition(int left, int right) { int pivot = A[right]; int i = left - 1; // 维护的划分中最右侧的比 pivot 小的元素的下标 // 遍历数组,把所有比 pivot 小的元素全部移动到左边 for (int j = left; j <= right - 1; j++) { // 遍历到 right - 1 可以对 pivot 进行保护,使得 pivot 不与自己对比,使逻辑更清晰,但或许没必要 if (A[j] < pivot) { i++; swap(A[i], A[j]); } // j 维护的是遍历时下标,当发现一个比 pivot 小的数时,如果 i + 1 == j 则不动,否则说明之前存在一个数比 `pivot` 大需要交换,则及时进行交换 } // 把 pivot 移回来 swap(A[i + 1], A[right]); return i + 1; } Hoare 划分 Hoare 划分采用双指针,进行交换。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int Hoare_Partition(int left, int right) { int pivot = A[left]; int pid = left; while (left < right) { while (left < right && A[right] >= pivot) { right--; } // 先从右往左扫描,保护 pivot while (left < right && A[left] <= pivot) { left++; } // 再从左往右扫描 swap(A[left], A[right]); // 交换不正确的数 } // 跳出循环时,left = right 说明找到了 pivot 的位置 swap(A[pid], A[left]); return pid; } 扫描顺序对于结果有影响。pivot 在最左边时,应该先从右往左扫描。 如果先从左往右扫,找第一个大于 pivot 的数 a,而第一个小于 pivot 的数在 a 左侧,此时进行 pivot 和 A[left] 的交换,会导致交换错误。故应该优先保证 pivot 左侧都小于等于 pivot,即先寻找第一个小于 pivot 的数,这样交换是安全的。 快速排序算法 对于某划分函数 partition(int st, int end) -> pivot: int 有 1 2 3 4 5 6 7 8 9 10 11 12 const int N; // 数组长度 int A[N]; // 待排序数组 void qsort(int st, int end){ if(st >= end) return; // 递归终止条件 int pivot = partition(st, end); // 递归 qsort(st, pivot-1); qsort(pivot+1, end); }

2025/9/11
articleCard.readMore

等待

此生此夜不长好,明月明年何处看? 雨巷独行,秉烛对月。我走遍了整座城市,却再也找不到那个独特的角落。或许只是那盏灯或那半掩的门扉,在人生之中却像风暴里海上的信标,似这江南春雨中云雾朦胧处,檐下的纸灯。旧梦重温,幼时在夏日熟睡,蝉鸣聒噪,也第一次为我定义了等待的焦虑。吊扇之下徘徊的影,是否还停留在多年前原地踟蹰。这种焦虑如影随形,如何能摆脱呢? 纪念我的第一次等待,或许也是一切不幸的开始。手术室的无影灯下,护士让我在门口先坐着等候。手术台上是谁?高台之上,一个迷茫的影。望不见,只感觉平静,右手的暗痛,仓促奔走多时后的终点。手术室。几分钟前在门外称重,一小时前乘汽车到来。回忆与梦夹杂。什么时候开始?你从一数到一百吧。那护士肯定觉得我不会,竟然用这种无聊的方式来哄骗我。到底要等多久?年幼的我真的在数数,一二三四五……不知道数了多久,忽然间没了意识,麻醉。下一个记忆片段便是走出医院,我或许躺在病床上被推出去,但我只记得医院的天花板,那玻璃天窗外明媚的阳光。回家的计程车,父亲的笑容,遥远的记忆,毛毯,被石膏束缚的右手,对话,呢喃。我在哪里?我等待了多久?那年我三岁。 后来在家旁的公交车站,那个盛夏,上小学之前,我在傍晚等待父母归来。或许是基因编码的本性,在黄昏来的,天昏地暗,当暮色蚕食最后一缕残阳,当夏蝉为坠落的太阳唱起挽歌,当路灯亮起,车灯流动,我也感受到一种从未有过的感受,如同草叶被风拂过,却难以恢复平静,露水撒了一地,又如同卧铺火车在午夜停止,静悄悄的深夜里,窗外的暴雨和风吟,下铺的男人低声梦语。公交车站旁是公路的起点,站后有一条河,河对岸是一眼望不尽的工厂。不知道多少车驶过,向路的尽头极目远眺,外婆的蓝布衫在暮霭里洇开。空气低沉,凝固,路灯忽明忽暗。我没有数一二三,我静静地听,静静地看。这里没有人也没有声音,只有蝉还在一遍一遍重复着那陈年老歌,每年不变的曲目。还有风吹过暗处的森林。 后来过去多少年,还有多少年,一直等待,那种感觉,或许被称为不安,被我带走了,从时间的起点带走了。为什么空间的障碍已经被科学打破,时间的乡愁永远难以抚慰?那么谁来拯救我迷失在多年之前的灵魂?谁来寻回我年幼无知,落在公交车站旁的安心? 梦游水乡,我在桥边等待一个人。是谁呢?来了才知道。桨声像细雨,低声讲述江南的故事。多少年运河,多少年前烟波画舫,文人墨客,一壶浊酒慰平生。多少年前传来了多少年后还会传唱的船歌。多少年前的多少年后在传承多少年后的多少年前的回忆。时间本无经纬,记忆自绣罗衣。那么等待也是。今天的等待,明天的等待。今天等待明天,那明天会不会等待今天? 你要等谁?水乡梦断,油纸伞下,苍老的容颜,道不尽平生的悲欢,古今都作渔樵闲话,尽付笑谈中。老者喟然长叹,似要给你讲述一生走南闯北的艰辛,那也是生活。你觉得你准备就绪了,你觉得你等待多年终于等到了人生的顿悟的时刻,那老者,只求你一壶酒一文钱,便把整个下午整个人生的经验都告诉你了。转头一看,却只听得风声雨声,和思绪如同奔流着的不息江河,在低声呢喃。 你还会等待,这卷青词从千年前汴河灯影里便开始书写,在一千年后也不会完结。

2025/3/29
articleCard.readMore

记梦(DeepSeek 辅助创作)

忆起一场梦 太累了 写得很烂 使用 DeepSeek 处理文章中的一些重复的段落 青石阶蜿蜒向上,尽头处悬着座褪色的庙宇。香火熏染的檐角垂着铜铃,风起时声响像隔世的叹息。你随人潮挪动脚步,鞋底碾碎阶缝里冒出的野蕨,一千零一个背影在你前方摇晃,恍若黄泉路上执伞的魂灵。 排队的过程中,有人给你讲起民间神话地方传说,谈天说地。从子夜饮沆瀣,至天明,山雾濡湿睫毛,长庚星与残月相望,你忽然记不起为何在此。你好像失去了感知。你不关心周围发生什么。你只是等待。你不知道你在等待什么,但是既然有等待的意义,那或许是有益的吧,这你倒是相信,你在等待什么?你不知道?你还真不知道。那你为什么要等?别问。你幻想到达之后的场景,脑海中酝酿一切计划,那跨过褪色门槛的刹那,即将到来的意义。老僧传授给你毕生的幸福,你参透人生之后一定要跨过远方的山,回到家乡,或者去旅行,或者去修行,或者?你首先要等待。 你等待。等待一千天,一万年,等到你白发苍苍。你立在庙门口。一座平常的寺庙,什么也没有。 推开褪色的木门,供桌上只有半截蜡烛。蒲团裂了口,露出里面的草絮。你是不是白等了? 但你还是不能走进寺庙。守门的老僧面色凝重,好像几百年前就站在这里,不允许来访者进入,而是设置层层关卡。老僧活像一尊石狮。你于是发问: 我什么时候能进去? 先数到一百。 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十。三十一。三十二。三十三。三十四。三十五。三十六。三十七。三十八。三十九。四十四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九一百。 不够虔诚 再来 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十。三十一。三十二。三十三。三十四。三十五。三十六。三十七。三十八。三十九。四十四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九一百 数错了 再来 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十。三十一。三十二。三十三。三十四。三十五。三十六。三十七。三十八。三十九。四十四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九一百 还是错了 再来 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十。三十一。三十二。三十三。三十四。三十五。三十六。三十七。三十八。三十九。四十四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九一百 依然错了 再来 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十。三十一。三十二。三十三。三十四。三十五。三十六。三十七。三十八。三十九。四十四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九一百 数错的太多了 再来 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十。三十一。三十二。三十三。三十四。三十五。三十六。三十七。三十八。三十九。四十四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九一百 再来 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十。三十一。三十二。三十三。三十四。三十五。三十六。三十七。三十八。三十九。四十四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九一百 再来 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十。三十一。三十二。三十三。三十四。三十五。三十六。三十七。三十八。三十九。四十四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九一百 不行。再来 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十。三十一。三十二。三十三。三十四。三十五。三十六。三十七。三十八。三十九。四十四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九一百 还是不行。再来 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十。三十一。三十二。三十三。三十四。三十五。三十六。三十七。三十八。三十九。四十四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九一百 …… 你数了千遍万遍,又是多少个日日夜夜,直到你用尽全部气力,奄奄一息。 我什么时候能进去? 现在还不行。继续数。 你为什么要进去为什么难道说里面真的有你想要的吗你为什么在这里为什么要等待为什么要数数为什么数错为什么不离开为什么不放弃为什么石阶吃掉了你的童年却吐出露水为什么苔藓在静脉里修建庙宇为什么数到七十九时心脏会长出年轮为什么乌鸦总在第九十九声啼哭里分娩铜铃为什么指甲缝渗出的血珠会自己滚成佛珠为什么山雾把肋骨腌制成经幡为什么白发垂落时听见蝴蝶振翅为什么掌纹裂开的沟壑里游着初生的你为什么不离开因为脚踝已生出根须为什么不放弃因为每次呼吸都在石阶刻下新的等高线为什么野蕨从眼眶钻出时带着乳香为什么铜锈味的月光正在翻译你腐烂的梦为什么山鬼的传说卡在喉骨为什么等待本身成了你唯一会诵的经文为什么庙门推开时涌出的是你三岁时的哭声为什么所有答案都在脊椎骨里结冰为什么你还在问为什么心跳总在测量与虚妄的距离为什么黎明前的黑暗有铁锈味为什么记忆的根系总在腐烂处萌发新芽为什么疼痛在骨缝里豢养萤火为什么沉默的舌苔上结满未爆的惊雷为什么时间的褶皱里藏着所有未被选择的自己为什么候鸟的归途比遗言更执着为什么伤口愈合时会听见星体坍缩的私语为什么孤独有海潮的咸涩为什么自由的边界生长着荆棘的经纬线为什么呼吸成为最昂贵的抵押物为什么月光把往事腌制成琥珀为什么希望是永不结痂的溃疡为什么死亡练习曲总在早餐时播放为什么活着需要不断吞咽自己碎掉的倒影为什么答案永远比疑问早衰为什么我们仍在所有破碎的镜像里打捞完整的指纹为什么宇宙的胎动与子宫的回声共振为什么墓碑是站立的河床为什么末班车总在泪腺决堤时到站为什么钟摆切割的光阴都带着血丝为什么最后的救赎藏在第一个伤口结出的珍珠里为什么坠落的花瓣在胃里修建天文馆为什么迁徙的候鸟总在掌纹迷路时投下阴影为什么结痂的伤口自动生成星图密码为什么溃散的晨雾要偷走瞳孔最后的焦距为什么发芽的骨缝里传出潮汐的旧唱片为什么褪色的誓言在血管豢养发光水母为什么腐烂的果核仍在拓印子宫胎动为什么冻结的时针以融水形态渗入骨髓为什么爆裂的沉默把声带锻造成青铜编钟为什么逃亡的月光在脊背凿刻甲骨文为什么解体的云层选择在舌根重新聚合成谶语为什么锈蚀的刀锋偏要收割自己种下的光芒为什么塌缩的梦境总在黎明前孵化成带鳞片的疑问为什么溺亡的钟摆仍在切割记忆的脐带为什么所有动词都在抵达终点前蜕变成墓碑的副词 为什么在这里为什么要等待为什么要数数为什么数错为什么不离开为什么不放弃为什么…… 你继续数。三十二遍时指甲掐破了掌心,七十五遍时数混了雨点数,第九十九遍总被乌鸦叫打断。有天摸到满头白发,才惊觉数数声已和心跳一样重。 再来 一二三四五六七八九十十一十二十三十四十五十六十七十八十九二十二十一二十二二十三二十四二十五二十六二十七二十八二十九三十三十一三十二三十三三十四三十五三十六三十七三十八三十九四十四十一四十二四十三四十四四十五四十六四十七四十八四十九五十五十一五十二五十三五十四五十五五十六五十七五十八五十九六十六十一六十二六十三六十四六十五六十六六十七六十八六十九七十七十一七十二七十三七十四七十五七十六七十七七十八七十九八十八十一八十二八十三八十四八十五八十六八十七八十八八十九九十九十一九十二九十三九十四九十五九十六九十七九十八九十九。 这下数对了? 错了,更错了,这一切尽是荒诞。 但你早已经身处寺庙之内了。你早就知道答案了。你不知道吗? 十九是晚自习教室的旧挂钟,二十八是钥匙断在锁孔的夜晚,三十七是母亲喊你吃饭的声音,五十七是月光在异地旅馆的窗帘游荡,六十六是第一次失恋那晚的星星。 但这寺庙里什么都没有啊,为什么还相信?你到底追求的是什么?是相信本身还是等待本身,都没有意义。或者说等待本身就是意义? 我不懂。你说什么? 数数本身就是人生,人生本身就是答案。这数数和等待都不是目的啊。那什么是目的?没有目的?还是全是目的? 四化作你七岁掉落的乳牙卡在门槛,十三变成母亲分娩时的汗珠渗进木纹,六十八正以你脊椎钙化的速率在瓦片上结霜。三十七粒星光在左肺叶发芽,五十九滴雨珠在右肾结晶,而那个永恒缺席的"一百",原来是你初生时剪断的脐带。 你说什么?可你为什么要数数?你为什么?啊?你喝多了吧。 当山风突然调转方向,你发现自己的白发正逆向生长成青丝。石阶上所有碾碎的野蕨突然开始倒放人生,第一千零一个信徒的背影里,你看见自己正从庙门倒退着走回起点,而数数声化作一串露珠,叮叮当当坠入你三岁时的奶瓶。 风突然卷走破庙,你站在岔路口。左边有人继续爬石阶,右边有人采野花。你踩了踩脚下新冒的蕨菜,转身朝没人的山坡走去。 露水打湿布鞋时,你想起七岁那年追过的红蜻蜓——它此刻正停在前方某根草叶上,翅膀载着三十年光阴。 最后,梦破碎了,醒过来。你不需要数了,你来去自由。你去哪里? 祝我十八岁生日快乐。

2025/3/13
articleCard.readMore

午夜飞行

你乘火车回到故乡。车厢里昏暗的灯光,颤抖着拼写出别离的感伤。窗外是多少山川岁月。倾倒的电线杆,望不到尽头的平原,水坝,大江东去,沿着车门一直伸展向世界的尽头。你所知道的只有这窗外的世界。多少片雪花落下,你不知道。你只知道故乡只存在于记忆深处,只在梦中重现。你只知道梦中有村庄,有微笑,有炊烟冉冉升起。都消散在风雨之中。 他在多媒体屏幕上点开下一部电影。数十小时的困倦从指尖生长到全身上下的每一根神经。惶恐在太平洋上空盘旋。为什么不承认错误?为什么匆匆下结论?什么也不懂。他想起午夜登山,山间的云气,雾里望月,日出,寒冷潮湿。手脚麻木,如浸湿在风雨里。他还是害怕。云间的那束暗红色的光,在飞机窗外跳跃闪烁,令人胆寒。 你在终点站前的车站下车。小贩兜售童年,你不记得是2011或是2013,火车上贩卖的廉价塑料拼图或是动车模型。世界新生伊始,江山如画,在那时画卷还未展开。你以为世界灿烂光明,你相信任何人,你充满了美好的梦想。动车还未修建,公路还未开始规划。盘山公路,数小时的行程,炸土豆,停顿歇息,继续上路。 他回忆为什么要远行。制服书写正义,正义竟然也让胜利者来定义,一切都由他们来定义。起初,他不相信。他在悬崖峭壁上如履平地,他不相信那些噩梦和神话。他甘愿相信那些美梦和空头支票,他默默承受,他学着众人的模样,在浅滩上奔跑。但他不知道生活是为了什么,他没有印象,只是希望向前奔跑。他认为自己有无限广阔的天地。 你追随祖先走向大海。那艘巨舰未能带走你那远代的先辈,信仰竟成为自己的棺木。路的尽头是一棵大树,你不知道为何总是对之生出莫名的敬畏。你其实从未到过这里,你从未和大山有过关联。这大山不属于你,你这外来者。但这是你的先祖曾扎根,曾生长的地方,曾经结束自己的一生,又曾坚守,曾被背叛。你没有记忆,历史的意义就是选择遗忘,或者,被迫忘记。 他不禁战栗,但机舱里并不寒冷。细想从来,他什么也没做错,却要受惩罚。他不知道这正义是否是正义,他只相信自己的权利,他只相信那与生俱来的权利。无理的规则多着呢,他不理解,也没有人解释。或许从来都不会有人质疑。但他吓都吓死了。删除一切记录,过去,好像从未发生。他什么都没做错啊。他不相信,他不理解,但很多事情都无法理解。是谁错了?他什么都没做错啊。 你说你如履薄冰,总是小心谨慎。你总是骂他不小心,但他确实没有犯错误。但你也开始恍惚,你不知道现在是什么年代。背负着五千年重担,只能忍痛前行,捍卫长城,或者固步自封,自鸣得意,或者这二者是在说同一件事情。你不继续说下去,让听者意会,你选择沉默。 他希望变成飞鸟,不受束缚,绕过太阳,飞向太空。他希望变成大海,冲破残阳,回到浅滩。他不懂什么叫爱情,他没有经验,他只能靠幻想。爱情比太阳更高尚,因为真实,因为自由。他回到水乡,在乌篷船里做那些好梦。船随着江涛规律摇晃,或许正好押韵于江南的诗行。但多少韵律都说不出他的怅然若失,他把一切梦幻寄托于那好梦,最终都成泡影。今宵酒醒何处,杨柳岸,晓风残月。他不懂,他对月抒怀,他抒不了怀。 你永远都回不到过去。过去的决定就是既成的事实,你只能接受,但你有时接受不了。接受不了也只能接受,有的是方法让你接受,温水煮青蛙,直到你低下头,教会你跪下来说话。你不信邪,你非要挑战,你非要试着唱反调。你自认为高贵,自认为独立于世间。你会发现你错了,你会发现你窒息在空气中。 天明前启程,城外多少朝代。他很崇拜那位诗人,像那位哲人一样,简直就是圣人。但他不相信权威,不相信个人的能力能够绝对凌驾于科学之上。一代一代的积压,民族的形状定型。他不敢相信,他不甘心,他非要试试。他太天真。在午夜,他还是会回想起那天,他已经下定决心。 你回不去了,你只能逆风向前。你被欺骗,你自我欺骗,也被别人欺骗。你好像在精神上被强奸了,被迫做自己不愿意相信的事情,但你不得不做,你不得不背上沉重的行囊,随着众人一起朝一个方向行走。你只能接受。他什么都没做错啊。 你发现他是贪生怕死之辈,只愿意维持现状。现状是一潭死水,他竟然只想苟且偷生,完全听凭别人摆布。你呼唤他前行,午夜飞行,你不知道飞向哪里。他什么都没做错啊。你只能追随祖先,祖先为你留下直觉和历史,你只能选择追随感觉。 他在午夜渡过这条河流,彼岸是什么,他不知道。冰冷的河水如藤蔓缠住他的小腿,刺痛他的神经,让他不敢再往前。他必须渡河,而不是停下来。他没有回头路,他不愿意再接受。他想起天明时看过的日出,骄阳似火,真理和真理之间只能有一个真理。真的是这样吗?或许不用毁灭,或许有更好的办法。金阁寺不用毁灭。他是对的吗? 你不再做梦,梦中只有惶恐。你放弃了信仰,你不再相信,你不再接受,你站起来,除去身上的灰尘。你要去哪里啊?你还相信吗? 你呐喊。你做了一个梦,梦里你呐喊。你找不到家了,你好像没有家。你在沙漠公路上独自前行,这条路没有尽头。总算没有人追赶你了,但你要去哪里呢?你往前走和往后走似乎是同一个方向。你要去哪里呢? 下了一夜的雪。他看不到故乡,也看不到目的地。午夜飞行,他还未落地。下了一夜的雪吗? 浅滩上,一轮明月,美好得让人愿意献出生命。但这些都不值得拯救,地面上的人不值得拯救。他放弃了使命,不空谈梦想,他先拯救自己。人生如梦。他第一次承认自己畏惧死亡。 你不相信梦想,你不相信陈见,你不相信权力和暴力,你不相信太阳,你不相信神话,你不相信别人,你不相信规则,你不相信故乡,你不相信过去,你不相信飞行,你不相信云,你不相信历史,你不相信直觉你不相信冰块你不相信大海你不相信微尘你不相信革命你不相信政治你不相信谎言你不相信幻觉不相信收音机不相信信标不相信城墙不相信诗人不相信江山不相信爱情不相信生活不相信文化不相信天气。你什么都不相信。你还相信什么?你还相信相信吗? 他没必要相信什么。他也不相信你,你只是午夜飞行的幻觉,只存在于过去,只属于天空。

2025/2/22
articleCard.readMore

桥梁

纪念一段往事 桥梁 / 小满 2024.2.1 于北京 白塔之上 寒鸦拼凑夜空 首都地铁四号线 匆匆驶向终点 是否通往明天的美梦 桥梁之下 雪与风相伴行走 惶恐化身暮霭 使落木飘零,放逐 来自幻想的春天 冰和天空衔接 联结了晓风残月与 昨夜的决绝 深秋的红叶终究飘向 冬天 记忆泛滥,凝固 月光没能到达目的地 而是灼烧 盈亏之间的伤痕 桥梁纠结,坍塌 海风将它托起 带回捡拾泡沫的沙滩 那日 踟蹰的光线 把夕阳和头发 搅成了一团 我总企盼有人重建桥梁 写给恍惚中度过的寒冷的秋冬

2025/1/7
articleCard.readMore

黎明 或 2012

旧诗一首 浅滩上 一群猴子说教 太阳未生的角落 玻璃杯破碎 火球燃烧 门外守着 枯萎的向日葵 熟稔的幽谷 光在其中窒息 然后 我嗅到了炊烟 黎明未造访的人间 鸡鸣、柴香中的生活 人在其中重生 停电的山村回归原始 黑夜吞噬 一盆热汽和滚烫的水 却是思乡的罪因 你说:一切往事都在梦中 幻影中 我听见—— 摩托和戒尺 喧哗的收音机 黎明在流血 伤痕滚烫 淌着东方的云 可我却期待黎明殒命: 献祭给了今天 才有明天 小满 2024/1/23 夜

2025/1/7
articleCard.readMore

RECAP2024: 水槛卧听雨

献给 2024,和梦中的水乡。 2024年的尽头,希望写下这些文字,脑海中却是虚空,难以回想起2024年发生的一切。这一年,太多变化,太多茫然,太多草率。选择总是觉得被动,在一个个被动的选择中拼凑出的2024。又想起上半年水乡中做的一场幽梦,阶前点滴的细雨,一直飘到2025的黎明。 那是梦中的水乡,细雨中,赶向最后一班乌篷。水槛中平卧听雨,凭栏远眺千年前流淌而至的京杭运河,却难以遣心。梦来的太恍惚,恍惚到2024年就如斜阳中彷徨的曲巷,猛然惊醒,才发觉这似梦非梦的都是真实的昨日。 不愿在水乡的幻想中迷失。一场雨下了三百六十五个日夜。向前,左转,再左转,右转,左转……小巷石砖,经受过多少年雨水。来不及撑起油纸素伞,也等不得细细品味这水乡的韵味。夏天的雨退行,行人退行,青瓦退行,三两枝竹退行。古琴洞箫在沉默中遁形,都市在水乡迷宫的出口等待。末班车的尾灯在水雾中变得模糊,似一团朱红的胭脂,从水乡戏台泼进城市的生活…… 2012 黎明在流血,伤痕里淌出东方的云。玻璃杯破碎,火球滚烫,浅滩上一群猴子无力地说教。这是世界末日前太阳为生的角落。 为什么最后的蒙特祖玛臣服于新西班牙,活人的祭祀仍在持续?为什么古代文明衰落,玛雅人的预言流传至今?黎明殒命,把昨日献祭,迎接新的光明。或有预感,2012就是2024。旧世界的终结会是新世界的开始。 太阳已将生命留给2023的白昼。你是将遭审判的囚徒,决绝将赴星月的刑场。2023年底,我化身为星光或者泡沫,去追随你的脚步。我祈祷直觉带领我寻觅你、追随你。 于是我的生命化为大海,在海风中,来到这2024。 寒鸦和桥梁 白塔之上,寒鸦拼凑夜空;首都地铁四号线,匆匆驶向终点。落叶被放逐归根。月光没能到达目的地,而是灼烧,盈亏之间的伤痕。那日,踟蹰的光线,把夕阳和头发,搅成了一团。 在北京,我仍然相信2023的直觉。圆明园的湖水冻成晶莹的镜面。我曾相信2024年也将如冰面一样澄澈光洁 我不能懂得十万里长城的无奈,用不变丈量未来,绘制出新一年的蓝图。终是一汪死水。 浮沉。北京的寒鸦带我回到那个冬季,漫步在中关村,在西单,在王府井。我不知道我的生命中是否还有北方,但那个冬天我愿意相信未来。 在天坛,祈年殿,雪花一片一片在天上流浪,飘舞似无所依附。我曾寄希望于雪花,曾认为找寻到了那一片雪花。它曾穿越风雪,休憩在我的窗前。而我曾用双手轻轻捧起,却发现雪花溶入了冬天的梦…… 水乡温柔 水乡温柔,何处是我家? 在错觉和现实交织的世界,繁花染遍大地,像一把火燃尽了整个春天。阳光灿烂,水乡并未给我选择,而是将我领向一片未知之地。我把这位置视为家,似乎找到了征途的歇脚处,找到了海边的永不褪去的泡沫。 在乌镇,迷失在水乡迷宫之中;在绍兴,凌晨踏上泥泞的山路,目睹黎明的再一次复苏。彻夜未眠。初夏的夜比现实更寒冷,山路崎岖比生命更曲折。只能彻底脱离对外界的依赖,成为极夜中的微光,引导着自己前行。 黑暗中举起手电,盘山公路上高歌。山上其实什么也没有啊!而我凭何找到慰藉,凭何找到光明?再次踏上蜕变之路,悟以往之不谏。我错了。我质疑过存在的存在,怀疑既成事实的真实,并寻求颠覆不存在的镣铐,走向歧路。 人生不是刻舟求剑,而且动态的、运动的。向前行,草木欣欣向荣,新的山巅上放声高歌,成为太阳,照亮长夜。不再相信,却更加相信。 午夜飞行 《新世界交响曲》慷慨激昂,却也流露出不稳定。午夜飞行,飞向纽约、亚特兰大和西雅图。新大陆从天际线上升起,为何旧大陆便消失得无影无踪。 在纽约,时代广场和布鲁克林桥,哥伦比亚大学校门外车水马龙,90号州际公路上凌晨的寒风与自然的呼吸。浦东机场,离别有了新的形状。 乡愁从此有了新的定义。望向从未登陆的领土,思念从未到过的故乡。宿命或者偶然,我又将踏上征途。此刻我却比任何时刻都热爱自己的土地,炎黄子孙的土地。 不断成长,不断蜕变。在香港漫步,棉絮一样的雾掩盖中环的摩天大楼,去远郊的山上徒步旅行,石澳村的海浪与泡沫点亮盛夏;在澳门,朝阳和金沙呈现同一颜色。上海图书馆,夕阳闯入二楼大厅,讲述盛夏的另一个故事——一场大雨。 晚风和暮云,午夜飞行。 后记 末班车怕是赶不上了。2024年的后半年,在矛盾和困惑中度过,却也大步向前走去。一个决定,一个决定未来10年的方向的决定,一个我未敢做出的决定。帷幕拉开,终究要面对,而所有的延迟都是徒劳。未来走向何处?我不知道,保留了决定的权利,而任自己在磨砺中不断蜕变。 2025年,不需要任何人的指引,摆脱真正的束缚,自由生活。不去做那些美梦,放下所有矛盾,一切都随水乡的烟雨飘散去了。 仍然需要幻想,但既已理清了这一些迷雾,也应坚定向前走去。昨天与明天一样飘渺,倒不如看着脚下的路,这近在眼前的真实。 不再随风、随雨、随大海,而是跟随自己,独立于世间,去追寻,去探索。 向山行,向山行,翻山越岭,没有终点,没有答案。 水槛卧听雨已成为往昔。2025,我将星夜兼程,片刻不息。

2024/12/31
articleCard.readMore

太阳、潮落

太阳 请给冬日动人的悲悯 你是空有光明的夜灯 无力带给寒天一丝暖意 太阳 请把生命留在白昼 你是将遭审判的囚徒 决绝将赴星月的刑场 太阳,伟大的事业未竟 你曾搏击北风,怒斥冬的不公 你曾笑对雪花妖冶的轻蔑 你是荒岭上的黄花 注定你的努力不合时宜 我在太阳中看见了我的生命 呐喊,口旁升腾的雾气 是传书于你的白鸽 聆听我的呼唤,太阳 我心意已决 请与我在海边坐待潮落

2024/1/1
articleCard.readMore

RECAP2023: 泡沫

浪声明朗,日光下, 我试着抓住大海 —— 它 却后退,化身成点点泡沫。 2023.8.10 《泡沫》 从夜梦中惊醒,已是黄昏。昨夜暖风似酒,酒醒时暮霭酡红。踏上驶向未知的火车,身后,残阳血溅寒天。瞭望窗外,时间向后划去似溢彩流光,在这光影之中,我看见了我的即将湮灭在过往的深夜里的2023。 2023,用一整年时间,独立海边,用一颗石子击打浪花,用一双手企图留住海潮。海风是一位吟游诗人,奔走四方,带来大海另一边的不同时空的故事——时空错乱,吟唱中我心渐静,双手空空。竭尽全力,扑向大海,攥住浪花——斜阳下,徒然攥住一手细沙,日光却告诉我这是黄金。海波泛起银光,似星海荡漾、转动,却从不能装进口袋,带进我的生活。 可是我仍矢志不渝,在海边,十二个月,追随海潮啊。 盛夏在青岛的碧海青天下留下自己的足迹,我的一年便停留在了那个下午的细雨之中。青岛车站,至今仍然保留着殖民地时期的风貌。砖红色的屋顶,静立在月色海风中,沉醉在浪涛的朦胧乐声中——那是不远处栈桥边的大海。意犹未尽,在清晨的细雨空蒙中,嗅着雨水中海草的腥味,那时陷入囹圄。旧的秩序已然崩塌。不愿面对的人群,永远说不出的心中的话语堆积,内心深处精神的孤独、缺氧,渐渐迷失在这片人生森林的迷雾中。 海风已熟习我一年来的故事,时间线错乱的故事经她们之口平静诉说。 在朝阳升起的地方,睁开双眼,柔焦,模糊的光影。我不再遗憾去年的流星雨,在新的一年开始的时候,一头撞向束缚我的桎梏——内心的无形的冰块。解冻,冰流潺湲。用身体中从夜中吸收的力量,向外迈步。 高楼之上,我受尽了曾以为伴的虚伪的恒星的炙烤。我手握剑柄,斩下那帷幕,所谓的光和热不再为我所闻。我囿于此,引来他的伙伴,试图渗透进我的身体,闯入我的陋舍——那闪烁的光。我曾以为那是我向往的泡沫的光影。 借五月假期之余,我回到杨浦,再会旧友。还望来时的路,始终留恋,四平路黄昏时的街灯,可是我不能再走在那路上了,可是我不能再去同济书店,看由粉转紫的彩霞,幻想地铁站中的惊喜奇遇。我看真切了,似梦似幻的过往,亦似往日居家的日子里从飘渺中飞来的隐约笛声。 在初秋,分道扬镳,而我也将走在我的道路上。分别的必然中,我回忆起相遇的偶然。去年在秋季的机房中相遇,如今听见那时的耳机里今日还在流淌的歌声,仍不时忆起你。想起春日里徘徊在机械零件中,春寒料峭,在车间中工作到深夜的日子。最终踟蹰于做出那个出国参赛的选择。逃过的数节课,工地办公室里的外卖,朝夕相处的日子。团委活动室棋盘上的故事,被偷走的象棋,“黑猫、白猫”的秘密。以至于后面的一个月,以及后面的半年,迷茫和野蛮生长。复杂的外面的世界,我不会忘记过往的紧锁心扉。我必须选择,于艳阳坠入大海之时,跃入海水之中。我的气息化成海风,我把生命献祭给大海,我的生命是大海,我得到了重生。 在天津,在北方,夕阳破碎,洒在林间枯枝之上,我第一次享受到恒星衰亡后的温热。这温暖由我自己创造。我成了我自己的太阳,这功劳也不在别人。答辩之时,找回一年前许下的从容。我将消灭一切阻碍前行的声音,我将消失在烟雨中,成为云海中的雾气,飘忽不定。北方没有烟雨,只有枯枝、败叶、寒风。 我用时间寻找松弛。有幸在满陇桂雨之中遇见了别样的杭州,在苏州品那一碗热雾腾腾汤面,在前滩偶遇晚霞的裂纹。苏子愀然对月,却在惠州再会了苏堤——玩月,丰、平二湖。春晓,此心安处是吾乡?自我在四方游历中重新获得定义。 那些有规律的自然的律动,是海潮给我的谆谆教诲。海潮涨落,我的心趋于平静。静谧的清晨,眺望大海及远方。海是印象派的交响乐,海是诗人未写完的诗行……细雨初歇。在中山路遇见一个少女,浅黄色渔夫帽下轻烟蔽月般看不真切的面容,缓步迈向咖啡店。她停下,把手机架在对面的墙上,小步跑向店门,在咖啡店门口的小桌上坐下,捧上一束花,调整仪态,微微一笑。她是在给自己拍照。一个人的旅行。雨后的阳光洒在咖啡馆的正门边,女孩刚才拍照的位置,玻璃台面反射出久违的光。而人生会是一场漫长的旅行…… 在四月的隔离教室中,追随光的脚步,唱起四月的歌声。正午的阳光,扰乱我的思绪。惊异于一年来学业长进,这却不是我出发时寻求的海浪。南京的长江边,朝阳下水鸟惊飞,浅紫色天空下的中山码头,我们一行人在江边打水漂。在夫子庙尝过一锅热气腾腾的粉丝,回忆中我再次来到那些重新认识自己的日子。江州的另一畔,巨轮驶来——仍遗憾从未到访过长江大桥和桥上携带夏天的火车……返校之后,走廊中的光影,我恍然得知惨痛的事实。 12月的上海,游园会上的重逢和小摊上操劳的信息组同学。一年前的相遇,如今我也成为“学长”,却仍然是第一次尝试。前路漫漫,缺乏经验指路。忘不了游园会的人群中,科目三的表演。锅里的热气腾腾不能打动固执的土豆,在必然的失败中,我们获得了部分胜利。文艺汇演,接二连三的彩排,尝试找到一个平衡点,度过渐渐熟悉的生活。舞台聚光灯下,演出圆满,观众席中飞来的荧光棒砸向谢幕演出的我们,不再寒冷。 ​学农和自己制作的鱼米饭、夜晚宿舍中的休整和抽象、与技术老师闲谈中结束的文艺汇演…离队时的稻田,一队人手持甘蔗,结队行阡陌,夕阳无限。寒空下地平线被点亮。暮色中,农户的秸秆燃烧,轻烟冉冉升起。黄昏已至,我是否应该回到家乡的土屋,享受那真切属于我的炊烟?半透明的残阳被烟遮蔽,彷徨,自由。 海风在呢喃。请告诉我2023的答案。一事无成?一路意外收获。 那我用何指引我的生活?前路比过往悠长,面向即将拉开的人生帷幕,缺乏力量和勇气。 2023将尽,海风仍不时抚过我的面颊,眼睑微润。海潮依旧涨落。下海,最后一次试图追上浪潮,试图一把抓起她,质问她,请教她。海潮拒绝我天真的问询,拒绝给予任何指引。我乞求的答案竟是泡沫。 泡沫,泡沫,2024请离开海岸,纵身跳入大海,化身大海,大海是答案,我的生命将是大海。 泡沫的银光中,怅然若失的一年溜走了。 我却会把泡沫视为2023最好的馈赠。 2024,相信直觉,相信自己。 Power Up. 还会继续忆起2023年海风的无形教诲

2023/12/29
articleCard.readMore

题解 P1622 释放囚犯

题目链接 题面 题目描述 Caima 王国中有一个奇怪的监狱,这个监狱一共有 PPP 个牢房,这些牢房一字排开,第 iii 个紧挨着第 i+1i+1i+1 个(最后一个除外)。现在正好牢房是满的。 上级下发了一个释放名单,要求每天释放名单上的一个人。这可把看守们吓得不轻,因为看守们知道,现在牢房中的 PPP 个人,可以相互之间传话。如果某个人离开了,那么原来和这个人能说上话的人,都会很气愤,导致他们那天会一直大吼大叫,搞得看守很头疼。如果给这些要发火的人吃上肉,他们就会安静点。 输入格式 第一行两个整数 PPP 和 QQQ,QQQ 表示释放名单上的人数; 第二行 QQQ 个整数,表示要释放哪些人,保证按递增的顺序给出。 输出格式 仅一行,表示最少要给多少人次送肉吃。 样例 #1 样例输入 #1 1 2 20 3 3 6 14 样例输出 #1 1 35 提示 样例说明 #1 先释放 141414 号监狱中的罪犯,要给 111 到 131313 号监狱和 151515 到 202020 号监狱中的 191919 人送肉吃;再释放 666 号监狱中的罪犯,要给 111 到 555 号监狱和 777 到 131313 号监狱中的 121212 人送肉吃;最后释放 333 号监狱中的罪犯,要给 111 到 222 号监狱和 444 到 555 号监狱中的 444 人送肉吃。 数据规模与约定 对于 50%50\%50% 的数据,1≤P≤1001 \le P \le 1001≤P≤100,1≤Q≤51 \le Q \le 51≤Q≤5; 对于 100%100\%100% 的数据,1≤P≤1031 \le P \le 10^31≤P≤103,1≤Q≤1001 \le Q \le 1001≤Q≤100,Q≤PQ \le PQ≤P,保证释放的人所在的牢房编号按递增的顺序给出。 思路 题意即求释放列表中所有罪犯的费用之和最小,每次释放,罪犯i到他两边空牢房之间的所有人,都需要消耗一块肉。每次释放一个罪犯,可以想到区间 DP,状态 f[l][r] 表示从l到r号罪犯全部释放所需要消耗的肉块总数。 之后思考状态转移方程。要求最小值,f[l][r] 初始值 INT_MAX。f[l][r] = min of f[l][m-1] + f[m+1][r] + Pos[r+1] - Pos[l-1] -2 ,其中 m 属于区间 [l,r],枚举合并点,即此次释放的罪犯,罪犯两侧到l和r号罪犯的消耗f[l][m-1]和f[m+1][r]。Pos[i]定义i号罪犯的编号。这里其实是一种反向的思路,m点应该是最先释放的(?Pos[r+1] - Pos[l-1] -2即此区间两侧最近的罪犯之间的人数,减去区间两端。即区间合并的额外费用。注意要在Pos数组中定义Pos[Q+1]=N+1。 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <cstdio> #include <cstring> #include <iostream> #include <climits> // For INT_MAX using namespace std; int Pos[110]; int f[110][110]; int main() { int P, Q; cin >> P >> Q; for(int i = 1; i<=Q; i++){ cin >> Pos[i]; } Pos[Q+1] = P+1; for(int k = 1; k<=Q; k++){ for(int i = 1; i+k-1<=Q; i++){ int y = i+k-1; f[i][y]=INT_MAX; // 初始值 for(int m = i; m<=y; m++){ f[i][y] = min(f[i][m-1] + f[m+1][y], f[i][y]); } f[i][y] += Pos[y+1] - Pos[i-1] -2; } } cout << f[1][Q] << endl; // 答案即把 1...Q 所有的罪犯全部释放(合并) return 0; } 小结 本题难点在于建模,区间DP部分比较典型。

2023/10/18
articleCard.readMore

题解 P5888 传球游戏

题目链接:P5888 题面 题目背景 羊城有善蹴鞠者。会足协之杯,于校园之东北角,施两球场,蹴鞠者站球场中,nnn 人,一球,二门,三裁判而已。观众团坐。少倾,但闻球场中哨声一响,满坐寂然,无敢哗者。 当是时,传球声,微微风声,队员疾跑声,教练呼喊声,拉拉队助威声,一时齐发,众妙毕备。满场观众无不伸颈,侧目,微笑,默叹,以为妙绝。 未几,我球员施一长传,彼球员截之,望我龙门冲来。 但见守门员 oql 立于门,若有所思—— 题目描述 原来他在想这么一个问题: 场上的 nnn 个球员围成一圈,编号从 111 到 nnn ,刚开始球在 111 号球员手中。一共 mmm 次传球,每次传球必须传给一个人,但不能传到自己手中。求第 mmm 次传球以后传回 111 号球员的方案数。 但他觉得这个问题太简单了,于是加了 kkk 条限制,每条限制形如 a,ba,ba,b,表示 aaa 号球员不能将球传给 bbb 号球员。 为了使得 oql 的注意力转移回球场上,你需要在最短的时间内告诉他这个方案数是多少。 你只需要告诉他答案对 998244353998244353998244353 取模后的结果。 输入格式 输入数据包括 k+1k+1k+1 行: 第一行三个整数 n,m,kn,m,kn,m,k,分表代表球员数,传球次数,限制条数。 接下来 kkk 行,每行两个整数 ai,bia_i,b_iai​,bi​,表示 aia_iai​ 号球员不能将球传给 bib_ibi​ 号球员。 数据保证不会出现不同的 i,ji,ji,j 使得 ai=aja_i=a_jai​=aj​ 且 bi=bjb_i=b_jbi​=bj​。 输出格式 输出一个整数,表示 mmm 轮后传回 111 号球员的合法方案数对 998244353998244353998244353 取模后的结果。 样例 #1 样例输入 #1 1 2 1 0 样例输出 #1 1 0 样例 #2 样例输入 #2 1 3 3 0 样例输出 #2 1 2 样例 #3 样例输入 #3 1 2 3 4 5 6 7 13 5 1 3 4 5 5 4 6 1 2 2 样例输出 #3 1 443723615 提示 对于 10%10\%10% 的数据,k=0k=0k=0。 对于另外 15%15\%15% 的数据,n≤500n\leq 500n≤500。 对于另外 20%20\%20% 的数据,n≤5×104n\leq 5\times 10^4n≤5×104。 对于另外 20%20\%20% 的数据,k≤300k\leq 300k≤300。 对于 100%100\%100% 的数据,1≤n≤1091\leq n\leq 10^91≤n≤109,0≤m≤2000\leq m\leq 2000≤m≤200,0≤k≤min⁡(n×(n−1),5×104)0\leq k \leq \min(n\times(n-1),5\times 10^4)0≤k≤min(n×(n−1),5×104),1≤ai,bi≤n1\leq a_i,b_i\leq n1≤ai​,bi​≤n,不保证 ai,bia_i,b_iai​,bi​ 不相等。 思路 首先看到题目,如果没有k限制,显然是DP。 设计状态 f[i][j] 表示第i局游戏传到j的方法数,显然满足 DP 的要求(无后效性、最优子结构等)。 得到状态转移方程:f[i][j] = sum of f[i-1][k]。其中k表示能够传到j的所有人。 但每次遍历k还是太麻烦,题目中显然能够传到j的人数大于受限人数。所以我们采用做差的方法,使用f[i][j] = sum of f[i-1][k] - f[i-1][m],此时k表示所有人,m表示不能传球的人。所有人的方法数和可以使用一个变量记录。 但是我们发现,题目中n的范围到1e9,显然无法开这么大的数组去算。 思考发现,题中限制数很少,只有5e4,最坏情况(限制中,a、b均不同),存在约束的人数也只有1e5,剩下的是毫无限制的“自由人”,因此可以简化问题,成为“自由人”、自己(即1)和“限制人”的传球游戏。 “自由人”可以“自传球”,需要注意。而且这样做之后,编号会混乱,我们需要创建一个map重新创建编号。 还有什么优化方法? 滚动数组,可以将f压缩! 代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 #include <iostream> #include <cstring> #include <algorithm> #include <queue> #include <map> using namespace std; #define MOD 998244353 struct Node{ int next, to; }NDS[100010]; int cnt = 0; int head[100010]; void add(int a, int b){ // 表示 a 不能收到 b 的球 NDS[cnt].to = b; NDS[cnt].next = head[a]; head[a] = cnt++; } vector<int> P; int DP[2][100010]; map<int, int> Dict; int main() { memset(head,-1,sizeof(head)); int n,m,k; cin >> n >> m >> k; for(int i = 1; i<=k; i++){ int a,b; cin >> a >> b; // remap int ida, idb; if(!(ida = Dict[a])) P.push_back(Dict[a] = ida = Dict.size()); if(!(idb = Dict[b])) P.push_back(Dict[b] = idb = Dict.size()); if(ida != idb) add(idb,ida); } // Sp: 1 -> 可能不是限制人,但是也需要单独更新状态! if (!Dict[1]) P.push_back(Dict[1] = Dict.size()); int Nc = Dict.size(); int Fc = n - Nc, idf = Dict.size()+1; // 记录此次和上一次的 Sum of f int sum = 1, sum2 = 0; DP[0][Dict[1]] = 1; // 初值 -> 只能从 1 开始传球 for(int i = 1; i<=m; i++){ int cur = i&1; // 滚动数组 int prev = 1-cur; sum2 = sum; sum = 0; for(int j : P){ DP[cur][j] = ((sum2 - DP[prev][j])%MOD + MOD)%MOD; for(int x = head[j]; x!=-1; x=NDS[x].next){ // 排除不能传球的人 int y = NDS[x].to; if(y==j) continue; DP[cur][j] = ((DP[cur][j] - DP[prev][y])%MOD + MOD) % MOD; } sum += DP[cur][j]; // 更新 sum sum %= MOD; } DP[cur][idf] = (1LL * sum2 * Fc % MOD - 1LL * DP[prev][idf] % MOD)%MOD; // 自传球 sum = (sum % MOD + DP[cur][idf] % MOD) % MOD; } cout << DP[m&1][Dict[1]]%MOD << endl; // 输出结果 return 0; } 更多注意事项 这道题我在取模的时候调了很久 -> “C++负数取模还是负数,应该将其变成正数” 小结 本题是一个动态规划问题,难点在于模型的建立。

2023/10/17
articleCard.readMore

残阳似火

“我的生命将是大海。” 青岛车站,至今仍然保留着殖民地时期的风貌。砖红色的屋顶,静立在月色海风中,沉醉在浪涛的朦胧乐声中——那是不远处栈桥边的大海。候车大厅静悄悄,耳畔不时传来广播的声响,也似轻烟一般飘渺,混杂着些泡面佐料的浓香,浮向大厅的远处。 这便是作别的日子,而这样的日子却总是意犹未尽。手指摩擦、转动手中返程的车票,不时看向手表上的时间——启程还有一个半小时。总觉得少了点什么,于是跑向车站内的小店,又空手而归。大海,是大海,作别大海,托付给她的不安被打包返还。 那天清晨的细雨空蒙,风却险些从我手中夺过那把随我走遍江南的雨伞。在滨海栈道上行走,新鲜的雨水混着海草的腥味,这是大海的馈赠,唤醒还未完全苏醒的我的灵魂。道旁的树用绿叶为这场夏日的开场仪式奏乐,窸窣窣,窸窣窣;海岸线上岩黄色的礁石屹立在大海之滨,沉思。近来可好?我的生活正在把我拖入泥泞,这里危机四伏,旧的秩序已然崩塌。不愿面对的人群,永远说不出的心中的话语堆积,内心深处精神的孤独、缺氧,渐渐迷失在这片人生森林的迷雾中。这便是那些为我定制的精神危机,我必须时刻斗争。礁石孤立无援,守在海岸的前线,听凭浪涛处置。 但浪涛仍是正义的。击打在这些巨石上,唰的巨响,溅起数米的水花,仍是治愈人心的。那些有规律的自然的律动,是海潮给我的谆谆教诲。但这些无形的空洞的响声,又有什么资格给予我未曾得到的生命力量?海潮涨落,我的心趋于平静。静谧的清晨,眺望大海及远方。海是印象派的交响乐,海是诗人未写完的诗行……细雨初歇。 向中山路走去,已经是正午。保留殖民地时期风貌的小街——精致的商品店、咖啡厅挤在单行道的两侧。墙边挂满了爬山虎,店门口的风铃和老式自行车,在微风中明朗清脆,便闻到一阵咖啡的幽香,嘴边感知到驱走今晨微寒的温热。在这里小憩片刻吧。远处走来一个少女,浅黄色渔夫帽下轻烟蔽月般看不真切的面容,缓步迈向咖啡店。便似飘散开奶香拿铁的甘甜,饮甘醉如熏,陶醉在细雨中微酡。她停下,把手机架在对面的墙上,小步跑向店门,在咖啡店门口的小桌上坐下,捧上一束花,找到更美的姿势,微微一笑。她是在给自己拍照。一个人的旅行也能如此!雨后的阳光洒在咖啡馆的正门边,女孩刚才拍照的位置,玻璃台面反射出久违的光。而人生会是一场漫长的旅行…… 时候不早,于是离开这里,想在返程前再看一次大海。海风仍抚过我的面颊,眼睑微润。海潮依旧涨落。下海,我试图追上浪潮,试图一把抓起她,质问她,请教她——我的生命需要方向。扑向大海,跌跟头,再爬起来,一把攥着涨来的海浪,手心冰凉,却发现是一捧金沙。海潮拒绝我热情的问询,拒绝救济迷失的灵魂。我乞求的答案竟是泡沫。 阿图姆苏醒,金红色的残阳,决然坠入深海。他果断选择了毁灭,选择了凤凰涅槃。残阳如火,大海也在海浪山崩地裂的哭喊中被夕阳的鲜血染成橘红色。陨落,金阁寺的火焰还未熄灭,碧海澄空在生命的火焰中熊熊燃烧。我想把我的生命此刻献祭给大海,寄希望于大海,期冀在运动中重塑生命。星海灿烂在夏日的毁灭中酝酿,“夜空一无所有,为何给我安慰?”海洋的呼吸滞碍我生命的前行。 生命本就是空虚的,一切也都是徒劳。夕阳在跟大海殊死拼搏中坠亡,何尝不是一种价值的创造?或许阳光会在另一面出现——那是远方的新世界。收拾行囊,准备第二天的征途,风的呢喃中,忘却生命之流中阻力与痛苦…… 车站里寂静无人,旅途已经完结,但人生的真正旅程甚至不能说已经开始。面对完全的未知和任由天命摆布的无奈,路途仍然由我们规划。 踏上列车,窗外夜空澄净无瑕,点点星光,这是星海的水波——我把海潮带走了,带向世界的每个角落,带向天涯海角,带向每一个夜晚和清晨。 海潮汩汩不停歇……

2023/10/13
articleCard.readMore

再会

懒得写简介,你们自己点进去看 doge 初秋的幽风再不能唤醒, 心中将干涸的冰流, 直到那西湖——野径清夜的回风 舞雪在我心中翩跹。 烟霞岭的桂香, 飘向幽谷和雪𪩘, 平湖秋月和断桥残雪。 苏子愀然对月, 却在惠州再会了苏堤—— 玩月,丰、平二湖。 春晓,此心安处是吾乡? 再会,上海的南京路, 一年前初秋的暖夜, 我曾如御西风, 也学那道家列子 ——大都会的夜不眠。 再会,当我发觉那将逝的、已逝的, 天下的美好,绝不能 再唤起我心中一丝快慰。 栈桥上残阳似火,我的生命在海浪、 在骤风细雨中熊熊燃烧: 生的火焰、死的火焰、 沟口的金阁寺的火焰。 再会,认真地, 再会,我亲爱的朋友和敌人, 素昧平生的人。 残酷的祛魅,意义的失去。 如今秋风与残阳萦绕我心——这是天谴。 湖上一轮明月, 太阳将在那后山诞生。 再会,那理性的感性的、 自然的和非自然的。 再会,旧的世界和秩序…… 再会,我不愿面朝大海, 再会,春暖花开。 再会,自私的我将把祝福留给自己 ——我不是数十年前那位伟大的诗人,更不会像他一样期待明天, 今日事今日毕。 置之死地而后生, 再会,支离破碎的自己。 世界在哲人的一声高呼中崩塌, 新的意义在废墟中出生。 那婴孩的啼哭,Nirvana…… 再会,为了再次相会。 那么, 再会,朋友, 别来无恙啊。

2023/10/6
articleCard.readMore

饥饿艺术家 卡夫卡

《饥饿表演艺术家》是卡夫卡曾计划印刷的短篇故事合集,他死后才出版。其中与合集同名的小说,也是最受他珍重的几个短篇小说之一。 故事情节大致如下: 多年前流行着一种饥饿艺术,人们争着来观看。饥饿艺术家往往为了艺术的荣誉感,自觉不去进食,而公众却会推选看守人员,看守人员也有意给他留空能偷偷吃东西。艺术家表现出自己挨饿的能力,希望消除人们的怀疑,可总有人不以为然。饥饿表演往往40天就结束,是为了能够保障收入最大化。经理会表现出对艺术家的赞叹,那至高无上的荣誉,人们的欢呼迎接,艺术家是不以为然的。那一切狂欢都是为了经理的营收。饥饿艺术家希望再饿一会,挑战极限。经理用各种解释和照片,使公众相信他的一套说辞。公众或许怜悯,或许怀疑,把艺术家当作江湖骗子。艺术家是不满意的,是不被理解的。 多年之后,当大街小巷饥饿表演不再风靡,人们又去追捧马戏团的表演,去看那笼中驯服的野兽。饥饿艺术被抛弃了?没有人会关注那旧事物那“江湖骗子”的消亡。艺术家也许应当转行,可他热爱这样的表演,告别了经理,前往大马戏团工作。马戏团里,他被安置在前往兽场的交通要道。人们在休息时间,赶去观看野兽的时候才或许会注意到他。他仍然表演,挑战自己的极限,可惜连记录他挨饿时间的工作人员都也离去。没有人在意他的成绩。人们更愿意去看野兽,人们把这饥饿艺术说是骗人的玩意儿。 表演结束,管事发现了笼子,发现了笼子里的艺术家。他还在坚持,他不愿意进食。“我只能挨饿,我没有别的办法。”“因为我找不到适合自己口味的食物。假如我找到这样的食物,请相信,我不会这样惊动视听,并像你和大家一样,吃得饱饱的。”他死了,他很坚定,他要继续饿下去。 笼子里换上了一只小豹,人们更爱看这只小豹,不舍得离去…… 这就是卡夫卡《饥饿表演艺术家》的情节。靠着挨饿表演换来观众的艺术家,在这种表演流行的时候不被理解,当表演不再流行便被人遗忘。他却坚持这种艺术,他认为饥饿是实现自己的方式,他找不到其他的方式,“只能挨饿,没有别的办法”。 “饥饿表演”、“40天挨饿”,故事荒诞,却引人深思,道出了深刻的真理。一个人,找到了他的热爱,实现他价值的道路,便愿意为此反抗世人不解的眼光,并愿意为此付出生命。一生的孤独落寞,一生的痛苦,在实现价值的时刻都不足挂齿。这件东西对于饥饿表演艺术家来说是饥饿表演,对于卡夫卡而言便是写作。写作对于卡夫卡来说很重要,他认为写作是“一种祈祷的形式”。 据说在卡夫卡去世前一个多月,他在病榻上阅读本篇清样时,不禁泪流满面,可见于书中主人公发生共鸣。 卡夫卡出生于奥匈帝国。他曾受过律师这门职业的培训,在他完成法学课程后在受聘于一家保险公司工作,任职后的空余时间,卡夫卡开始写短篇故事。对于工作剩余的时间,卡夫卡经常会抱怨难有较充裕的业余时间从事写作,因为自己不得不将大量时间去工作。他后悔对他的Brotberuf(“日常工作”,即“生计”)投入了过多的关注。因为欧洲当时对犹太人的压迫排挤,卡夫卡时常曾抱怨自己身为一名犹太人。他对犹太人处境的低下、被动的埋怨与不满也对他作品的风格有影响,但卡夫卡自认为身为犹太人却对自己没有起多大的帮助。卡夫卡在世时并不有名,大多数作品都是去世之后发表的,他在辞世之后才变得有名。 或许卡夫卡也是这样一位“饥饿艺术家”,用自己独特的荒诞文学希望实现自己的价值。生前并不被大众看好,遗嘱中本希望把作品销毁,作品却被朋友发表,才被世人所知。 他热爱写作,敬畏文字,工作之余进行自己的“饥饿表演”。 因为除了写作,他别无他法。

2023/8/15
articleCard.readMore

Python 中的 zip() 和 enumerate()

最近要用 Python 做一些小项目,记录一些学习心得。以及这个博客再不更新技术文章,就变成文学博客了,显然和初衷相违背() zip() zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象。 1 2 3 4 5 6 7 8 >>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> c = [4, 5, 6] >>> zipped = zip(a, b, c) >>> zipped <zip object at 0x00000278786975C0> >>> list(zipped) [(1, 4, 4), (2, 5, 5), (3, 6, 6)] 这样做的一种应用方式是在遍历的时候,可以同时遍历多个数组: 1 2 3 4 5 6 >>> for i, j, k in zip(a, b, c): ... print(i, j, k) ... 1 4 4 2 5 5 3 6 6 如果遇到数组不等长,会以最短的长度为准。 如果要按照最长的长度,可以使用另一个函数 zip_longest(),不多赘述。 enumerate() enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和索引。 1 2 3 >>> seasons = ['Spring', 'Summer', 'Fall', 'Winter'] >>> list(enumerate(seasons)) [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] 这也可以在遍历的时候使用。 注意事项 这两个函数使用的时候,需要导入模块 itertools,否则会报错。

2023/8/11
articleCard.readMore

泡沫

只恨一切都成了泡沫…… 浪声明朗,日光下, 我试着抓住大海——它 却后退,化身成点点泡沫。 海波泛起星光闪烁, 如秋波传情勾起那些缅邈之怀。 这次,要抓牢—— 海无情,夕有情, 斜阳下,攥住一手细沙,金黄。 奔走,奔走,向大海, 跟随泡沫的踪迹。 前行,浪声明朗, 拽住浪花似TA的衣袖, 只恨,跌倒,潮退, 失去。 迷茫。 泡沫,泡沫, 如今我两手空空。 “虽不能至,然心向往之。” 或许会随波流浪, 去大海深处, 去寻觅你, 寻觅浪声依旧。

2023/8/10
articleCard.readMore

“救救孩子……”——谈鲁迅和《狂人日记》

“救救孩子……” 渐弱的呼喊,鲁迅在狂人的绝望中收束全篇。这种无力却格外让人感觉似有一股刺骨之寒,或能于铁屋中惊起更多较清醒的“不幸者”。 铁屋中觉醒 鲁迅“到N进K学堂“,研习格致、算学之类。眼界开阔了,方才醒悟中医或许并非治人之病的良方,而还有更多像他的父亲一样得不到科学的治疗的国人。于是他赴日留学,专攻医术。某日,他观看的日俄战争的影片中,同样是中国人,“一个绑在中间,许多站在左右,一样是强壮的体格,而显出麻木的神情。”“据解说,绑着的是替俄国做了军事上的侦探,正要被日军砍下头颅来示众,而围着的便是来赏鉴这示众的盛举的人们。“人们欢呼。在中国,日俄的冲突而被日本人斩首示众的中国人,中国人在旁观,中国人在高呼”万岁“。鲁迅心中震颤,便下定决心”改变他们的精神“,”提倡文艺运动“。 这是《呐喊》自序所述。或许驱使鲁迅下定如此决心的,并非如此一次观影经历,而是长期以来所见、所思。中国人病了,病在精神上,病得不轻。 他想寻找同志。器物救国的道路指引下,“东京的留学生很有学法政理化以至警察工业的,但没有人治文学和美术。” 最后邀集了几人,愿出杂志《新生》,却在出版之前各自退出。寂寞,鲁迅如是形容。没有人赞和,没有人反对。根本没有反响。悲哀啊,寂寞啊。鲁迅面对的是一片荒原。“这经验使我反省,看见自己了:就是我决不是一个振臂一呼应者云集的英雄。” 寂寞的痛苦中,鲁迅在S会馆抄古碑,甘愿让自己的生命暗暗地消去。这是他的麻醉,许多年,直到钱玄同来访——此时他们正办《新青年》,对着荒原呐喊。“你抄这些有什么用?”“没有什么用。”……“我想,你可以做点文章……”钱玄同希望鲁迅为《新青年》撰稿。 “假如一间铁屋子,是绝无窗户而万难破毁的,里面有许多熟睡的人们,不久都要闷死了,然而是从昏睡入死灭,并不感到就死的悲哀。现在你大嚷起来,惊起了较为清醒的几个人,使这不幸的少数者来受无可挽救的临终的苦楚,你倒以为对得起他们么?” “然而几个人既然起来,你不能说决没有毁坏这铁屋的希望。” 希望?希望。希望!希望照亮困顿。鲁迅最终答应,于是便有了此篇《狂人日记》。 在寂寞里奔驰,呐喊…… 狂人的妥协 在序言中,鲁迅写道这狂人是他中学时良友之弟,患”迫害狂“之类,写下的日记。”语颇错杂无伦次,又多荒唐之言“。如今病愈,却赴某地候补了。 全文实在荒唐,却让人害怕。狂人起先觉得这赵家的狗多看他两眼,需小心。之后又觉赵贵翁和那路上的人,似怕他,又似想害他,需提防。随即,路上孩子、街上的女人、家里的人、哥哥……一切的人,都被他所怀疑。他觉着全村的人似乎有要吃他的阴谋。最后却发现自己不仅是“受害者”,也是“加害者”,和他们一样——或许妹子就是被哥哥所食,或许她的肉或在饭菜里也被全家人食用。便发出“没有吃过人的孩子,或者还有?”之问,是对这个吃人世界之外的净土的追寻。 吃人并非是吃的尽是肉体,也可以是精神。吃人并非一定需要尖牙利齿,也可以用“仁义道德”取而代之。 凡事总须研究,才会明白。古来时常吃人,我也还记得,可是不甚清楚。我翻开历史一查,这历史没有年代,歪歪斜斜的每叶〔页〕上都写着“仁义道德”几个字。我横竖睡不着,仔细看了半夜,才从字缝里看出字来,满本都写着两个字是“吃人”! 狂人到底还是语无伦次。易牙和桀纣并非同时代的人,《本草纲目》并不是《本草拾遗》。但吃人的历史没有年代。古代,有“易子而食”,易牙可以把儿子蒸了先给齐桓公;当代,打儿子可以“咬几口出气”,“给知县打枷过的,也有给绅士掌过嘴的,也有衙役占了他妻子的,也有老子娘被债主逼死的”也都可以理所应当。“去年城里杀了犯人,还有一个生痨病的人,用馒头蘸血舐。””大恶人,给大家打死了;几个人便挖出他的心肝来,用油煎炒”吃,可以壮壮胆子。”从盘古开天辟地开始吃人,吃到易牙的儿子,吃到现在。“好人”可以吃“恶人”,“恶人”活该被吃。理由便是“仁义道德”。 狂人意识到了“吃人”的事实,找身边的人,希望劝转他们,却被当成了“疯子”。或许这与鲁迅的寂寞之痛也是相通的。意识到自己也是食人者后,感叹“难见真的人!”这是一个人吃人的社会,希望便给了下一代。 “救救孩子……” 可惜,抱有如此希望,已经发现了如此真相,在“病愈”之后,他却候补,听候委用,愿入朝做官。这或许又是一种妥协?发现吃人真相的异类,在吃人的社会中,如此谋求生存。 在铁屋里醒来,又在装睡罢了? 希望、责任,给予下一代人。 “救救孩子……” 下一代人不应受到“吃人文化”的摧残,应当摒弃这些错误的保守的所谓“仁义道德”。孩子不再吃人,社会也不再会是“吃人的社会”。“救救孩子”中蕴含“孩子救救”的祈祷。 “这人肉的筵宴现在还排着,有许多人还想一直排下去。扫荡这些食人者,掀掉这筵席,毁坏这厨房,则是现在的青年的使命。” 引用鲁迅《灯下漫笔》作结。

2023/8/9
articleCard.readMore

想念

好久不见啊! 古罗马的斗兽场,数千年矗立在地中海沿岸的小城。蒙蒙细雨,如游丝,洗濯时间长河中穿梭着的风尘仆仆的旅客。 或许想起在烟雨江南,于靉叇之下缦立,远眺城墙之外。人们总是刻意忽视时间,以为出了这城便是乡。城门启,谁知,还乡,物是人非。 乡愁,一如浪潮袭击海边的渔村,无情地将我拽入不见底的深渊,黑暗的虚空。一说是时间的乡愁,想念幼时河边游遗失的安心。山脚下的村庄飘来了袅袅炊烟,乡间蒸饭和热油下锅的气息,勾引我千里之外的魂魄。记忆中我还是个孩童,手握竹竿,站立在山间公路的转角。山路十八弯,那就是我的故乡。 外婆怎么还没有喊我回去吃饭?外公怎么没有骑着摩托从水电站回来?记得那时深夜,轰鸣声悠长,打破夏日鸣蝉。空气中凝固的不安的气息解冻,随即是柴门闻犬吠,风雪夜归人。向山行,向山行,爷爷却让父亲走出大山。 那天,外公载我游遍深山,县界的隧道、县外的群山,白溢寨和千丈岩,国家公园。紧握他的衣袖,疾风起,敞开外公的衣裳,军绿色的夹克。那时尚未老去,路边点起一支烟。随风飘,一缕长烟细,似那天的云霭。 后来,在山上的爷爷家,那夜难眠。离了父母,幼小的孩童,素未谋面的血亲。窗外萤火虫闪烁,也像外公的烟烬,如今何处去寻那夜啊!野草微摇,农舍内烧开的热水上水气弥漫。轰鸣,外公接我回去。 许多年的故事,许多年的分别,渐忘了回家的路。回不去的是那时岁月。未变的是群山。 也思念旧时老友,那时校园漫步,无话不谈。花团锦簇,蜂蝶飞舞,也如我们闲行的身影。深夜的信息,闻知重逢的良机,急行,赶向过往的烟云中。往事如烟,往事并不如烟。初见,相视无言。熟稔地挑起熟悉的话题,冰冷中见真情。 那时或在夕阳西下之时,暮色之下慢跑。少年在微光中,希望在梦想中。天色渐暗,灯起,前路初现。后来迈步衢上,回首向来萧瑟处,也无风雨也无晴。归去,归不去。校园芳草依旧,故人不再。未变。真的没有改变吗?变化的是时间,是韶光。逝者如斯,如今我却思念,思念那些流水年华。 回到故乡,重返校园,时间的乡愁责罚无罪的我。天啊,为什么鞭笞时间中无辜的行人,用不尽的情感之潮,浇灭我向前的火种。总要向前行,却无法阻止自己向后看。勇气,向着未知。失去的岁月、人、事,一切,回忆中变得绚丽。 又是一年盛夏,从故乡乘高铁归来。夕阳下,原野平静,我心难平。慢一点,远去的大山不再停留。或许远方还有人在思念。相思,苦涩。落日,无情。 谁怕,此心安处是吾乡? 想念……

2023/6/10
articleCard.readMore

浅滩

秋潮涨落, 在那心的桥梁。 彼岸还有草露甘香。 春泥, 是明天的味道。 明天?回答今日的困惑—— 海的女儿, 带来独木扁舟, 和那风的号角。 浅滩上, 思绪是雨燕, 盘旋徘徊在碧海青天。 飞去!远行! 散不去的是层雾迷蒙。 潮起,潮落, 潮水在我脑海的浅滩起落。 潮水啊,何时平息在大海的尽头? ——大海一刻不停,在欢唱: “生生不息……“ 秋潮带走了我, 浅滩上, 我还是我的我, 我的生命将是大海。

2023/3/30
articleCard.readMore

蝉 · 夏

一 六月的鸣蝉嘒嘒,微弱却唱响夜空。 路旁的小楼上,沐心倚着阳台的栏杆,远眺万里澄澈的夜空。偌大的城市。车水马龙,光线在飞驰而过的喧闹声中划过眼前的夜。她又在极目远眺。但早就没有什么人让她这样等待了,她也不再是当年的孩童了。 沐心家在郊区,上海的郊区。远方的铁道线路,路旁树丛中窸窸窣窣的夏夜之歌,沐心心里却是另一番景象。此时她正看着稀少的来往车辆,发着呆。她喜欢这样,在夜晚思考。但她的确没有思考什么。 “那些……所以……” 她似在嘀咕着。这心中涌动的问与答不小心说了出口。 脸庞淡红,她忽地四下望,慌乱中险些将手中的笔丢到轻盈的夏季的空气中,坠落。好在四周没有人。毕竟那很是尴尬呢。 绿化带上,花丛中飘来淡淡清香。 回到起居室内,墙壁上贴着几面镜子。夏季新雨过后,燥热却仍带湿润的空气早已给镜面蒙了一层纱。不知是深夜的恍惚,还是水雾幻境,亦或者是幻觉,沐心在镜中看见了自己的倩影,似在清澈的梦境中漂浮。奇怪,明明是夏季,南方夏日,心里实在是一丝寒冷,太凉了。镜中,她看见了眼角带着一些满溢的温热的湿润。或许是水汽,或许……她莞尔一笑,或是笑情绪真是捉摸不透。 但刚才面对广袤深空,感受大地和城市脉搏,她确是有些言语未说出口。蝉鸣替她讲完了口边的千言万语。 横道线,柏油路,黑白漆。入夜,染上了淡蓝,仿佛被水蒙盖一般奇妙。 交通信号灯还在闪烁。 二 泪眼迷蒙中,她又开始远望。她看见的不是山,不是海,不是坠入大地的夕阳。她看见了虚空,夜晚。星稀疏,一颗、两颗——那是飞机。 高处风疾。她扣上毛线衫的扣子,双手在胸前轻抚。很是清凉。触摸耳旁,发丝不经意间滑过那手。碧发微寒。 蝉鸣还未歇。 夜晚带她去往十多年之前。 那时,在公路道口,夹竹桃盛开的地方,外婆带着她等待晚归的父母。 那时,经济发展迅速,这样的千年古国展露出蓬勃生机。这座国际大都市,上海,自然吸引了许多投机者,创立企业。她的父母便是这样的人,不过,他们算是后来者。不知有没有赶上末班车了。沐心只在政治课上偶然了解了这些,那些政治课也不知她是如何度过时光的。 不过她记得,每个这样的黄昏,她都和外婆在这里等待。那时她五岁。 闷热的天气,潮湿的衬衫,实在是让人喘不过气来。夕阳把碧空染成火的颜色,高速路边绿树成荫。道口有一个公交车站,却少有行人。这是终点站。 她不在乎来往的车辆,不在乎来往的行人。她极目远眺,希望见到一个骑摩托车的身影。那是父亲。 她若有所思,发呆的习惯或许是从这一刻开始的。 蝉鸣窸窸窣窣,知了知了…… 外婆通常不会说话,这是她的性格。沐心很少了解到外婆的故事,却只是知道外婆是母亲从远在山区的老家叫来照看她的。不过那时外婆也还年轻。 “妈妈她们快回来了,很快的。” “嗯……“ 等待中,夕阳已从树梢落入地平线,斗转星移,繁星点点。她看着来往车辆,鸣笛声也像水流般从她耳侧淌过。天空中还是有飞机,但她没有兴趣。她看向昏暗的树林,似乎感觉有什么可怕的东西要冲出来。那或许是外婆口中传说的野兽,吓唬小孩子的什么东西。她或许从没有信以为真。但那些恐惧是有名字的,就是她心中的不安。 阳光沉入大地,她心里却只是想,他们怎么还不回来,他们什么时候回来。从小一个人成长,也不懂得与人们交流。她很是不安。 蝉鸣越来越急了,她心烦意乱。 这时微风拂面,她的发丝飘摇。游丝一般的闷热依然萦绕,担忧阴魂不散。 但远处骑着黑色摩托的熟悉身影到来,她心中的石头沉下来了。蝉鸣声不息,窸窸窣窣。她的眼泪都快落下来了。 后面的事,她的记忆便不太清晰了。但那种缺乏安全感的混乱,却被她带走了,直到今天。 三 她往往是沉默的,她看似少年老成,内心活动却异常丰富。她不善与人相处,却又渴求一种她自己也说明不清的东西。她曾在回忆中搜寻,在散步时追问。没有答案。所以她在痛苦什么?所以她在追寻什么? 铁道线上,地铁飞驰而过打断了她的思绪。 地铁?初中时期,沐心就每天乘地铁上学。地铁飞驰而过,空气的清澈声响,让她倍感亲切。 曾经有一阵子,沐心确实以为自己得到了自己想要的东西。 一头乌黑秀发的少年,成绩也是不错呢。性格活泼,又有一些调皮。他那时在班上也很受欢迎吧。少年名叫晨星,是沐心的同班同学,性格却完全相反。但不知什么机缘巧合,两个人相识了,相处还算是愉快。不过如今沐心也记不得什么了,断绝往来,只能叹息人性虚伪咯。 不过,他们曾经每周的书店之旅,却实在是难忘。 学校门口,桂花盛开。学校在上海的老城区,学校是一所老学校。放学时间,同学都围在门口小卖店,谈论最新的电影、小说,嬉戏打闹。马路上车流不断,天空是浅粉色。 放学之后,他们会去快餐店买那几元钱的小吃,也会去书店闲逛。书店边是一所大学,学校里树林茂盛,那时也快到了樱花盛开的季节。 那时,沐心的整个世界崩塌了。她只记得自己病了,心病了。冰冷的世界,冷漠的人潮,她只觉得人性冷淡,觉得世界陌生,觉得处处敌对。暗淡无光的眸子中,泪光常挂。但连泪光也是无力的。只有那叹息声中还能听得出一些希望。 书店之行就是她生活中的光。 “我喜欢川端康成,我要做那样的小说家。” “嗯,他的书确实不错。我也喜欢。” 晨星介绍自己热爱的数目,沐心便看到了少年朝气,有的时候还为这种感觉感动呢。 那段时间,沐心差点自杀了。那段时间,她确实死了,但她重生了。 还记得她“回来”之后,面对十一月冰冷的夜空,在南京路上轻盈的步伐,和朋友逛街探店,脸上的欢笑。 夕阳斜照,步行街上,她感觉在微风中,她要飞起来了。 草木微动,澄空微寒。 四 蝉鸣声不歇的夏季,沐心这次有些迷茫。 她经历了太多,比眼前马路上来往的车辆数多多了。无数次的等待,无数次陪伴和冷落。她还在追寻什么,她向往的生活是什么? 她自己也不知道。 独立?自由?爱? 她缺少家庭的温暖,缺少真实的交流。对,确实是这样。 但她又确实不缺少什么。 蝉鸣声窸窸窣窣。她的思忖永无休止。 她仇恨吗?有一点。 但她早已知道,过去的世界已经在幻梦中走向消亡。 门铃声响。父亲夜晚回家。 她好像幻听。“抱歉,久等了。“ 没有声音。 ”回来了。“ 无数次的等待,无数次的不安。 幼时曾担心而哭泣。长大后,这一切都有了新的含义。 未来想来会不会觉得幼稚? 但在这些经历中,她变了。 …… 蝉鸣声不息,空气闷热。窗口亮起昏暗的灯火。那是远方的村庄。她睡去了,泪光比夜空澄澈。

2023/3/25
articleCard.readMore

微风

少年的长发,飘扬在微风明朗的五月。 气息中还带有一丝土壤的味道,絮飞扬,花洒地。昨夜的雨是否浸湿了娇嫩的绿叶,沉睡的草木醒来,便是疯狂滋长。入夏,蝉鸣。 斗转星移的深邃海洋,飞鸟划过夜空。空中若隐若现的涟漪,像那些出海的日子,海鸥溅起片片水花,如同敲击冰面的冰花。 少年就这样望。在窗边望,在小院思。院门外鸡狗声未歇,在看不到的角落,或许行人惊醒了沉睡的生机。但哪有什么行人?半夜三更。…… 少年要去赴那六月的邀约,回到想象中水墨山水的西湖。湖上的蓬舟,水上的浮木,船夫用船桨在水中留下的草书笔画,是否如兰亭的碑文。未有形先有情。浊酒一杯,彻夜不眠。湖上附着的水汽的薄膜,如莅仙界。少年想起了少女的素娟,柔转、飞舞,牵动的情思。然而透过西湖的雾色面纱,黑暗难以辨识的远山上还有昏黄的灯火。山外是否有人家?山中行,耕作、饮酒、作诗,砍柴喂马。天下遨游,睥睨万物。 可惜少年在那个五月出发去了远方。那是一种生命中或许只能有一次的奇妙旅行。穿过意识深处的山野,在荒郊城外的林间小路行走,踏上天空。天空或许有局限。囚禁在这里,在树林、在空间穿梭,在时间。少年困在现在,现在摆脱不了少年的束缚。莫名的苦痛,眼角的泪花。变幻莫测的时空,这个世界上必然有能容少年之地?沉入深海。 湖光山色,天快亮了。船上是少女的笑颜。粉色的天空,浅蓝的湖水,纯洁的白雾。碧竹编成的蓬舟,如今历经沧桑,泛黄。忽然飘起了雪花,一片一片,粉白的澄空中,一片一片。 少女起身,船头眺望。一望无际的湖山。少年是否长存天地之间?逍遥自在,山间村居。少女不知道,但或许少年在她中存在,谁知道呢。一段未有人诉说的故事,或许来年春天向我们讲述? 少女的长发,飘扬在微风明朗的十二月。

2023/3/12
articleCard.readMore

观星

二月快乐! 今夜的我 没有篝火 山歌和露水 立在窗前好似身处一片虚无 触不可及的,是 那飘渺的月的诗行 和缠绵悱恻的繁星的歌谣, 都随我进入那清风入夜而归。 何归也? 窗前的虚无, 天真的人们把他称作“星空”。 那是人类的终极宿命, 从参宿四出发, 半人马座、小熊座、双鱼座。 总有一个地方, 觅遍那枯肠, 也要寻得恰如其分的比喻, 倾诉跨越光年的思忖。 光年之外, 琴声来自光年之外, 那一刻我变成了光, 光变成了宇宙。 那是 137 亿年前的消息, 今夜向我诉说, 或许如《百年孤独》一般, 命中注定和羊皮卷, 正等待我破译。 地球上, 诗人写下诗行, 被天地之间的人们传唱; 宇宙间, 银河里盛满了今夜我心中的泪, 而我的空虚也有宇宙广大。 今夜, 我当织女, 而那逝去的过往便是我的牛郎, 只恨过往再难相遇。 世事繁杂, 车水马龙, 搅乱我 绵延至数个天文单位外的 联结, 是同那宇宙, 和那过往的云霭。 在世界寻不得自己的位置, 我愿远去, 去那星云之间, 做一颗即将诞生的恒星, 光热,照亮世间的层雾。 今夜的你 没有篝火 山歌和露水, 两手空空来敲我的家门, 何妨? 好在还有封存的记忆。 远行, 去脱离着轮回, 挣脱指数级的孤独的束缚。 远行, 不知东方既白。

2023/2/1
articleCard.readMore

浮尘

最近尝试随便乱写点诗歌。 微尘, 浮沉, 孤身行大漠的旅人。 跨越了半个世纪的风雪, 休憩在我的窗前。 行大漠, 越风雪, 如今在太阳的怒吼下, 飞舞, 浮沉, 像个不懂事的孩子。 微尘 浮沉, 微不足道的力量, 却敢向那太阳挑衅, 从不笃信是那太阳给了他生命和舞蹈。 跨越了半个世纪的风雪 休憩在我的窗前, 又用那剩下的半个世纪, 完成未竟的事业, 挑战太阳, 飞舞, 浮沉。 东方的太阳, 强壮的战士, 沉没在西方的深海。 火种熄灭。 熄灭, 浮尘, 黑暗中舞蹈。 黑暗中孕育着新的太阳。

2023/1/27
articleCard.readMore

复活

岁月如梭;来日方长。 幻想自己的模样,并被如今吓一跳。是时候启航了,这一次去更远的地方,用更好的航海术。 光,是流水划过我的眼眸。睁开双眼,柔焦,模糊的光影。眼角之间,好像有什么粘稠作一团的东西,阻碍着光线的生长。眼角还有泪痕,仿佛昨夜一场梦境初醒,却信以为真,身临其境,不能自拔,深陷其中而感受到的虚弱。是的,我无法抬起我的双臂,使出全身力气,不能控制我的双腿。我的身体脱离了束缚,或者说,我的灵魂脱离了束缚。肉体存在于很远的地方,要等待醒来的召唤,解除夜的梦的封锁。在梦境里,无法做出选择,对着变化的世界,旋转,眩晕。光丝在眼中生长扩散,舒展开的肌肉,双眉。醒来之后又有一个梦,梦里还有梦,环环相扣,人生只不过是众多梦境中的一个,何必分清虚实。 起身,又是一个清晨,叹息已经注定了一天的重复的单调。穿衣,刷牙,洗脸,整理,打扮,重复的早餐,三明治配牛奶。仍有气无力打开电脑,Telegram、微信、Visual Studio Code。很好,不出所料的没有新信息。手机上,微信群里的声音却已经让人厌倦,甚至让人想要卸载微信,清空所有联系。不过是一些交流群、同学群,却没有勇气,或者说没有兴趣点开那空白的输入框。就像新建文件却不知道填写什么标题,删除,再新建,永无休止才发现一个上午的时间早已流失;就像站立的荒芜的水泥地上,而这水泥地正在你的脚下崩裂,坠入黑暗的深渊,在边境之地徘徊,悬浮,却没有勇气向下一看惊喜地发现离地半米,有惊无险。人或许是危险的,就像孤身一人行走在原始森林,对周围的风吹草动担惊受怕,哪怕只是一只弱小的蚂蚁。毕竟是一个人。过去,行走在人潮涌动的商业区,南京东路,看着来往的人流,交通警察维持秩序,店员售卖琳琅满目的商品。灯火通明,夜空被霓虹招牌点亮,灯下袅袅的烟霭,路边摊的烧烤,远处的香味。那一个晚上或许只是一场梦。接近人潮,不安,抗拒,这样的喧闹只让人心神不宁,甚至不愿与那店员交易换取心仪的纪念商品。这种萦绕的思忖,反复涌动如同这来往的不断地人潮,脑海中,一个开启就无法关闭的收音机,播放我听不懂的语言,蜂鸣。紧接着是静穆,远处来往的地铁。溺亡,在自己创造的声音的海洋中。但今天,我祈祷免受折磨,免于崩溃。 正午,日光击在窗前,我心中一颤,好像听到了太阳的搏击。地面是纸屑,却像五月的碎玻璃。但那或许只是我的谎言。那天玻璃杯无故坠地破碎。那天重拾起封印的记忆。想起以前,能有一个在自己控制之内的圈子,便就能满足,便把自己锁起来,独享安宁。想到往昔的隐者,自耕自食。回不去又何必在谈起。于是写下,逃离舒适圈,说起,自己不再能满足的丑话。谁知是如今的窘迫。幸于能收获一线庇护,一丝未来的希冀吧。由是感激。虽然有时甚至觉得上天不公,背叛了我,私自选择了我的诞生,选择了我的社会身份,选择了一切,但来了总不能留下遗憾。是吗? 手机上有了新通知?起身,弹出座位,一把抓住手机,扯下充电线,按开屏幕,划出通知栏,却发现是垃圾邮件。不知道在期待什么啊!微信上,重复发出的表情,解释说自己变了,辩解说自己开心。狡辩。也罢,往事如烟。长期行走在痛苦的边缘,过去是否真正互相理解?不过站在当今看过去,就连最悲惨的都被珍惜。也是可笑,人类如何能做到有这么多情感,我又如何能做到如此在意?我不在意,我要逃离那个地方,逃离这个纷繁的世界。我要回到我的世界。 冰雪融化,却是在午后。太阳似乎要吞噬这座内心的冰城,而水流也已近干涸。破开生活的茧,破开自己已知的世界,走向未知。此刻我是那个好奇的初生的生命,探索从未涉足的领域,社会的领域。打开围栏,打开窗户,像鸟飞向远方。重生,或许是复活。但是生与死没有界限,生即是死,死即是生。如此说,这是我的第5783次。手起刀落,斩断流动的人潮,斩断隔膜,铲除混响的收音机。我疯了,但我没疯。这个世界上有太多的人,他们疯了?当世界上所有人都不能理解我的内心,他们疯了还是我疯了?他们不正常还是我不正常?没有人是对的,没有人是错的。切断这个梦的天际,让我重新控制我的身体。太久的沉寂,我需要醒来。向外界迈出新的一步,这一次步态坚定。试图融入,试图改变,试图接受。永恒的不是闭塞,而是万象更新的生气。并庆祝我此刻的存在。是的,谢天谢地我活下来了。不说改变世界的空话,先提升自己。 还是想起某一个午后,约定去书店。那时候的内心世界阴沉,你是一束光照进了我,穿透了我,我醒了,我悟了。翻动书本,立志一起追逐天边的太阳;在夜晚也会歌唱,围炉夜话,谈论琐碎的小事。买一瓶奶茶,把它弄洒,还有河流上的风。五彩斑斓的世界,从痛苦的记忆中走出,感受到生活的真实。我真实存在着。你不懂,我以为你懂了。这是无意之举。或许又有一天,午后,却因为一点点小分歧,餐盘打翻在空中,我的悔恨从此不再离开。但那不是你,但那是我未能送上的歉意,是我欠下的一笔债,无处去还。默默祈祷自己的转变。不在意,不评论。只谈论自己,太久不奋力拼搏,如今的我要为生存,为生活反抗,反抗世界,反抗天地。并且但愿我不是孤身一人。 身体中充满力量,前进的动力,那些过去或许一起说过的话。没有道路就创造道路,没有条件就创造条件,没有方法就创造方法。“骗谁呢。”但如今的确可以再拿出来,想着许诺的未来迈进了,但是想到少了点什么。 复活?你说只是来到了下一层炼狱。 炼狱就炼狱。我喜欢这里,因为不经受考验,就不再会有成长。我感恩痛苦,感恩打击;我祈祷痛苦,祈祷夜幕降临,纵使繁星点点无法入眠,脑海中思绪不受控制,不受限制。 夜幕真的降临了。Wish you were here. 但 You are always here 不是吗。可能吧。但我要远航了,去那遥远的地方。带上希望。复活。

2023/1/11
articleCard.readMore

【摘录 | 转载】普鲁斯特 《追忆似水年华》第一卷 《在斯万家那边》(一)

摘录一些最近正在拜读的作品。 P46~50 就这样,在很长一段时期内,每当我半夜梦中回忆及贡布雷的时候,就只看到这么一块光明,孤零零地显现在茫茫黑暗之中,象腾空而起的焰火,象照亮建筑物一角的电光,其余部分都沉没在黑夜里。这块光明上尖下宽:下面是小客厅、餐厅、花园中幽暗小径的开头一截(无意中造成我哀愁的祸首斯万先生要从那面走来)和门厅(我要由此而踏上楼梯的第一级),而攀登起来令我心碎的楼梯则构成这个不规则棱锥体的非常狭窄的锥干;顶部是我的卧室、卧室外的过道、过道口的玻璃门,我的母亲就是从那里进来的。总之,老在晚上那个钟点见到、同周围事物完全隔绝、在黑暗中孤零零地显现的,就是这么一幕简而又简的布景(等于一般老式剧本的开头为供外省演出参考而作的布景提示),为了重演我更衣上床的那出戏,这些道具是少得不能再少了;似乎贡布雷只有楼上楼下,由一部小小的楼梯连接上下,似乎只有晚上七点钟这一个时辰。说实话,倘若有人盘问我,我或许会说贡布雷还 有别的东西,别的时辰。但,那将是我有意追忆,动脑筋才想到的一鳞半爪;而有意追忆所得到的印象并不能保存历历在目的往事,反正我决不会自愿地去回想贡布雷的其他往事。它们在我的心目中其实早已死了。 永远消亡了?可能吧。 这方面偶然的因素很多,而次要的偶然,例如我们偶然死去,往往不允许我们久久期待首要的偶然带来的好处。 我觉得凯尔特人的信仰很合情理。他们相信,我们的亲人死去之后,灵魂会被拘禁在一些下等物种的躯壳内;例如一头野兽,一株草木,或者一件无生物,将成为他们灵魂的归宿,我们确实以为他们已死,直到有一天——不少人碰不到这一天——我们赶巧经过某一棵树,而树里偏偏拘禁着他们的灵魂。于是灵魂颤动起来,呼唤我们,我们倘若听出他们的叫唤,禁术也就随之破解。他们的灵魂得以解脱,他们战胜了死亡,又回来同我们一起生活。 往事也一样。我们想方设法追忆,总是枉费心机,绞尽脑汁都无济于事。它藏在脑海之外,非智力所能及;它隐蔽在某件我们意想不到的物体之中(藏匿在那件物体所给予我们的感觉之中),而那件东西我们在死亡之前能否遇到,则全凭偶然,说不定我们到死都碰不到。 这已经是很多很多年前的事了,除了同我上床睡觉有关的一些情节和环境外,贡布雷的其他往事对我来说早已化为乌有。可是有一年冬天,我回到家里,母亲见我冷成那样,便劝我喝点茶暖暖身子。而我平时是不喝茶的,所以我先说不喝,后来不知怎么又改变了主意。母亲着人拿来一块点心,是那种又矮又胖名叫“小玛德莱娜”的点心,看来象是用扇贝壳那样的点心模子做的。那天天色陰沉,而且第二天也不见得会晴朗,我的心情很压抑,无意中舀了一勺茶送到嘴边。起先我已掰了一块“小玛德莱娜”放进茶水准备泡软后食用。带着点心渣的那一勺茶碰到我的上腭,顿时使我混身一震,我注意到我身上发生了非同小可的变化。一种舒坦的快感传遍全身,我感到超尘脱俗,却不知出自何因。我只觉得人生一世,荣辱得失都清淡如水,背时遭劫亦无甚大碍,所谓人生短促,不过是一时幻觉;那情形好比恋爱发生的作用,它以一种可贵的精神充实了我。也许,这感觉并非来自外界,它本来就是我自己。我不再感到平庸、猥琐、凡俗。这股强烈的快感是从哪里涌出来的?我感到它同茶水和点心的滋味有关,但它又远远超出滋味,肯定同味觉的性质不一样。那么,它从何而来?又意味着什么?哪里才能领受到它?我喝第二口时感觉比第一口要淡薄,第三口比第二口更微乎其微。该到此为止了,饮茶的功效看来每况愈下。显然我所追求的真实并不在于茶水之中,而在于我的内心。茶味唤醒了我心中的真实,但并不认识它,所以只能泛泛地重复几次,而且其力道一次比一次减弱。我无法说清这种感觉究竟证明什么,但是我只求能够让它再次出现,原封不动地供我受用,使我最终彻悟。我放下茶杯,转向我的内心。只有我的心才能发现事实真相。可是如何寻找?我毫无把握,总觉得心力不逮;这颗心既是探索者,又是它应该探索的场地,而它使尽全身解数都将无济于事。探索吗?又不仅仅是探索:还 得创造。这颗心灵面临着某些还 不存在的东西,只有它才能使这些东西成为现实,并把它们引进光明中来。 我又回过头来苦思冥想:那种陌生的情境究竟是什么?它那样令人心醉,又那样实实在在,然而却没有任何合乎逻辑的证据,只有明白无误的感受,其它感受同它相比都失去了明显的迹象。我要设法让它再现风姿,我通过思索又追忆喝第一口茶时的感觉。我又体会到同样的感觉,但没有进一步领悟它的真相。我要思想再作努力,召回逝去的感受。为了不让要捕捉的感受在折返时受到破坏,我排除了一切障碍,一切与此无关的杂念。我闭目塞听,不让自己的感官受附近声音的影响而分散注意。可是我的思想却枉费力气,毫无收获。我于是强迫它暂作我本来不许它作的松弛,逼它想点别的事情,让它在作最后一次拚搏前休养生息。尔后,我先给它腾出场地,再把第一口茶的滋味送到它的跟前。这时我感到内心深处有什么东西在颤抖,而且有所活动,象是要浮上来,好似有人从深深的海底打捞起什么东西,我不知道那是什么,只觉得它在慢慢升起;我感到它遇到阻力,我听到它浮升时一路发出汩汩的声响。 不用说,在我的内心深处搏动着的,一定是形象,一定是视觉的回忆,它同味觉联系在一起,试图随味觉而来到我的面前。只是它太遥远、太模糊,我勉强才看到一点不陰不陽的反光,其中混杂着一股杂色斑驳、捉摸不定的漩涡;但是我无法分辨它的形状,我无法象询问唯一能作出解释的知情人那样,求它阐明它的同龄伙伴、亲密朋友——味觉——所表示的含义,我无法请它告诉我这一感觉同哪种特殊场合有关,与从前的哪一个时期相连。 这渺茫的回忆,这由同样的瞬间的吸引力从遥遥远方来到我的内心深处,触动、震撼和撩拨起来的往昔的瞬间,最终能不能浮升到我清醒的意识的表面?我不知道。现在我什么感觉都没有了,它不再往上升,也许又沉下去了;谁知道它还 会不会再从混沌的黑暗中飘浮起来?我得十次、八次地再作努力,我得俯身寻问。懦怯总是让我们知难而退,避开丰功伟业的建树,如今它又劝我半途而废,劝我喝茶时干脆只想想今天的烦恼,只想想不难消受的明天的期望。 然而,回忆却突然出现了:那点心的滋味就是我在贡布雷时某一个星期天早晨吃到过的“小玛德莱娜”的滋味(因为那天我在做弥撒前没有出门),我到莱奥妮姨妈的房内去请安,她把一块“小玛德莱娜”放到不知是茶叶泡的还 是椴花泡的茶水中去浸过之后送给我吃。见到那种点心,我还 想不起这件往事,等我尝到味道,往事才浮上心头;也许因为那种点心我常在点心盘中见过,并没有拿来尝尝,它们的形象早已与贡布雷的日日夜夜脱离,倒是与眼下的日子更关系密切;也许因为贡布雷的往事被抛却在记忆之外太久,已经陈迹依稀,影消形散;凡形状,一旦消褪或者一旦黯然,便失去足以与意识会合的扩张能力,连扇贝形的小点心也不例外,虽然它的模样丰满肥腴、令人垂涎,虽然点心的四周还 有那么规整、那么一丝不苟的绉褶。但是气味和滋味却会在形销之后长期存在,即使人亡物毁,久远的往事了无陈迹,唯独气味和滋味虽说更脆弱却更有生命力;虽说更虚幻却更经久不散,更忠贞不矢,它们仍然对依稀往事寄托着回忆、期待和希望,它们以几乎无从辨认的蛛丝马迹,坚强不屈地支撑起整座回忆的巨厦。 虽然我当时并不知道——得等到以后才发现——为什么那件往事竟使我那么高兴,但是我一旦品出那点心的滋味同我的姨妈给我吃过的点心的滋味一样,她住过的那幢面临大街的灰楼便象舞台布景一样呈现在我的眼前,而且同另一幢面对花园的小楼贴在一起,那小楼是专为我的父母盖的,位于灰楼的后面(在这以前,我历历在目的只有父母的小楼);随着灰楼而来的是城里的景象,从早到晚每时每刻的情状,午饭前他们让我去玩的那个广场,我奔走过的街巷以及晴天我们散步经过的地方。就象日本人爱玩的那种游戏一样:他们抓一把起先没有明显区别的碎纸片,扔进一只盛满清水的大碗里,碎纸片着水之后便伸展开来,出现不同的轮廓,泛起不同的颜色,千姿百态,变成花,变成楼阁,变成人物,而且人物都五官可辨,须眉毕现;同样,那时我们家花园里的各色鲜花,还 有斯万先生家花园里的姹紫嫣红,还 有维福纳河塘里飘浮的睡莲,还 有善良的村民和他们的小屋,还 有教堂,还 有贡布雷的一切和市镇周围的景物,全都显出形迹,并且逼真而实在,大街小巷和花园都从我的茶杯中脱颖而出。

2023/1/4
articleCard.readMore

Time - Pink Floyd - The Dark Side of the Moon

Having pored over the lyrics, I have these comments: Nobody to show us the way, nobody to tell you when to run, no chance to catch up with the sun. It’s late and you’ve been getting closer to death. So get home and see the rain. Paralyzed, missed out on the sunshine and at last forever wandering. Links YouTube | Wikipedia

2022/12/29
articleCard.readMore

【转载】静夜思变调

转载一首好诗。 故乡,留下一段回忆,过去的我在现在的我在未来的我,萦绕,怀念。可惜故乡,可恨昨天只隔数小时,却比月还遥远。 毕竟,一秒钟的距离便是到宇宙毁灭的距离了。 生命是瞬间。 原文:熊秉明 ·《静夜思变调》 一 序 大诗人的小诗 从椽笔的毫端落出来 像一滴偶然 不能再小的小诗 而它已岸然存在 它已是我们少不了的 它在我们学母语的开始 在我们学步走向世界的开始 在所有的诗的开始 在童年预言未来成年的远行 在故乡预言未来远行人的归心 游子将通过童年预约的乡思 在月光里俯仰怅望 于是听见自己的声音伴着土地的召唤 甘蔗田 棉花地 红色的大河 外婆家的小桥石榴.... 织成一支魔笛的小曲 二 一个古老的诗国 有一个白发的诗人 拈一片霜的月光 凝成一首小诗 给所有的孩子们唱 一代一代地唱 会须一饮三百杯 老诗人捞月去了 小诗留在月光里悠扬 在故乡悠扬 在他乡悠扬 三 祖父的老花眼镜边 折射出菜油灯黄黄的火苗 床前明月光 疑是地上霜 祖父的花白胡子里 漏出袅袅烈草烟味的青烟 举头望明月 低头思故乡 爷爷,我会背了。」 眼镜后面的眼角上有一点泪 胡子后面的嘴里没有牙 孩子,玩去吧!」 四 床前明月光 疑是地 上霜 举头 望 望 明 明 月 低头 思故 思故 思故乡 床前月光 疑地上霜 举头明月 低头思乡 床前光 地上霜 望明月 思故乡 月光 是霜 望月 思乡 月霜 望乡 五 姐姐 你还记得吗? 在月光里 你曾玲珑地望 床前明月光 疑是...真是... 真是霜一样的月光呵 后面的两句呢? 我带它们走了 走了半个世纪 走到没有土瓜和鸡棕的地方 没有麦粑粑和过桥米线.... 举头望明月 低头...举头... 六 床前明月光 疑是地上霜 祖父教的第一首唐诗 于是拍着双手 踏着院子的石板 着迷地唱 明月光 地上霜 地上霜 明月光 孩子已作了祖父 过去的孩子在今天的祖父心里 顽童一样着迷地唱 思故乡 思故乡 思故乡 思故乡 七 月光里的故乡 月明了的故乡 故乡时的明月 故乡思的月光 什么时候起 迷作一片朦胧 乡 即是 月 月 即是 乡 迷迷 疑疑 望望 茫茫 注满眼底 溢出眼外 月月乡乡 圆了的月啊 月了的乡 八 在时间的那一头 在世界的那一头 拍着手 拉着手 孩子唱 望明月 问明月 月光光 明月乡 在时间的这一头 在世界的这一头 举头 低头 满头霜 满头霜 满眼老花的月亮 满面粼粼的月光 九 低头思故乡 马锅头他们一定 还在横断山脉里 横断着山的脊梁 高山的风和日敲他们的铜脸 水牛一定还在红河水里 轻盈地浮沉黑铁的犄角 甘蔗的汁比红河水更浓 炼成霜色的冰糖 每一个结晶的面都闪闪地唱 床前明月光 十 昨天母亲来信说 我好 你好吗? 我给母亲回信 我好 您好吗? 月亮是苍白的 月亮不说话 故乡比月 更远 一倍 十一 疑是霜 疑是霜 悄然落在书页上是一丝闪闪的白发悄然 落在书页上不再是青色的发丝了那曾是 父亲的白发使我心惊的悄然落在书页上 而今是我自己的白发悄然落在书页上而 今只有我自己的白发了悄然落在书页上.. 举头望 举头望 十二 低头思故乡 我已回去 我已回不去 我已不回去 我已在路上 秦时明月汉时关 我已渴毙 我已骨折 丝绸的路 骆驼、石头和骷髅的路 床前明月光 十三 床前明月光 节节骨痛的床 没有床的稻草垫 没有稻草的泥地 没有泥地的水门汀 水湿的枕头 火热的枕头 没有枕头的 惊醒的失眠的 眼闪着月光 疑是地上霜 十四 举头望 举头望 中秋月从楼影后面探过来 圆了白净的脸 圆了惊异的眼 咦 怎么没有月饼? 怎么没有栗子和梨? 怎么没有柿子和枣? 没有红的蜡烛? 没有香炉和香? 连圆的桌子也没有 握一卷太白诗集在背后 静悄悄地 月亮看我 我看月亮 十五 好月光 好月光 唱一支歌儿吧 咱们唱 松花江上 唱咱们都会唱的 不行 不行 我不能唱 我不能唱 一唱声音就呜咽了 再唱嗓子就哽住了 三唱眼晴就什么也看不见了 你们唱 我跟着 我的家.... 在....在 在东北松花... 江上.. 十六 这是诗 这是一首诗 这是一首中国孩子学的 第一首中国诗 大家跟我念 床前明月光 疑是地上霜 举头望明月 低头思故乡 熟麦的鬈发 海水的眼晴 比越女更白 琳琅错乱的回声 太白 大概 大笑了 十七 三个孩子到中国去了 两个大学生一个中学生 只会说小学生的中文 第一次见到北京的老祖母 献上什么礼物呢? 别忘了背一首中国诗 床前 明月光 疑是 地上霜 低头 思 思 思 全家人都笑了 九十岁的老祖母 笑出眼泪来 用宽的袖口揩着 十八 我走 我跑 我停下来 我走 我跑 我停下来 孩子 你是干什么啊? 妈妈 月亮老跟着我 十九 七十岁的中国人 住在赫德森河畔 解开领带 泡一杯清茶 ──黄河之水天上来 一口乡音未改 七十岁的中国人 放上电剃刀 顾盼两鬓的白发 疑是地上霜的白发 三千丈 缘愁似个长 七十一岁的中国人 举头霜 低头霜 黄河长 明月乡 七十二岁 解开领带 泡一杯清茶 黄河之水天上来 弃我去者不复回 七十三岁 三川雪满魂飞苦 蜀道之难天梯石栈明月相钩连 何茫然 催心肝 七十四 七十五 解开领带 泡一杯黄河 朝如青丝不可留 乱我心者暮成雪 七十六 七十七 拿起电剃刀 断水水更流 长相思 白云间 长相思 彩云间 七十八 黄河三千丈 何处是故乡 朝辞去 不复回 七十九 白发黄河天上来 奔流到海不复回 八十 不复回 不复回 黄河 黄河 天上 天上 不复回

2022/12/23
articleCard.readMore

高楼 幻梦 冰

去那意识模糊到与现实交织成如糨糊般粘稠一团的地方,看一看那座冰雪的迷宫。同样的幻境,同样的梦。反复。 在不知何时,单手撑在桌上,光略显阴暗。今日或许降了雪,冷风吹进暖气中温热的室内。感觉有点闷。那就索性开窗吧!窗外的世界也没想到那般萧索了,路灯暗下,也几乎见不得什么了,只剩远处的虚空中高楼顶上还亮着的些许红光。但我的耳边听见了风的牧笛,风的萨克斯,风的交响乐。七月的原野上,远方传来的或许也是相似的声音。日光渗到每一棵小草,给予大地无尽的能量。悠扬的笛声从远方飘来,勾引的我的魂魄。 凭窗伫立,看腻的风景,不过空荡的街道和周而复始的交通灯。这个世界自己在运动。稀疏到几乎没有的车流,来到时还会细致观察车牌。许久之前,当我还是一个好奇的幼儿,我更会细致地看,细致地望,留心每一个细节。那时的光阴,几乎都无法感知到流去的速度。如今却今非昔比了,如今沧海却以变为桑田了。 整日积攒下来的重负,沉重,酸痛,胀在我的脑中,堆积在我的前额,压下我的双眉,顺着脸庞的线条,刺痛的颈椎,脊椎。之后一股股热流涌动,我的大臂开始无力,我的小腿失去知觉,我的脊背不能承受而弯曲。痛苦地与疲惫对峙,穿过筋疲力尽的峭壁,来到宁静与永恒的内心森林,直到握笔都似有些抖动。我如一位即将消逝为尘土的老者,精神即将消散的睡眠的幻梦中。或许梦是现实世界的暂时崩塌。毕竟当你闭上眼睛,当你与现实断开一切的联系,起初还能感知到的呼吸和身体与棉被、床罩和那一系列柔和的有些滑溜溜的东西接触的感觉,之后又如同肉体抽离了一样的时候,你已经不再以平常的形式存在了。你不存在,你的精神去了另一个世界,幻想的世界。 眼前已经看不到什么了,只剩下空洞的静穆;耳边不再有音乐,而是无尽的虚空。但我的精神是自由的,可以来往于世界上任何一个角落。我与世界上任何一个人,都建立了一种现实中敢都不敢想,也绝不可能建立的牢固的链接,似乎宇宙大爆炸前就在那里了。是的,就在那里。自由穿行,我被赋予了超越人类的能力。我分不清哪个是现实了。 眼前是北京香山的枫叶,纽约时代广场的雪花,伦敦的泰晤士河上的游船,香港的高楼。我发现我身处冰块之中;我发现我以我幻想的样子存在,一个本属于我又不属于我的躯体,一个本属于我又不属于我的形态。我发现我回到了生命诞生之前的地方,光产生的地方,回到了万物起源的神圣殿堂。意识是流动的液体,思绪是漂流的枫叶,荡起涟漪。在光的照耀下,意识的水中波光粼粼,荡起水花。每一刻,都有一个人被照亮。他的精神被点亮,他的肉体被点亮,他被点亮。但这不是兰亭,没有流觞曲水的娱乐,更不会有古代的隐者。这是我们内心深处的地方,是我们的灵魂所居的地方,是我们自己又不是我们自己。 冰块闪耀,封印了几个世纪为被人发觉的胜过世界上任何意见雕塑作品的雕花。冰屋里,透过晶莹又朦胧的冰幕,隔绝又无比接近地走进她的生命,他的生命,你的生命,我的生命。我发现我是所有人,我发现我谁也不是。一个人睡着了便不再有记忆了,因而我感觉我从未存在过。是的,眼前是不真实的谎言。《波西米亚狂想曲》中,未曾被赋予生命的愿景又何尝不是一种解脱?可惜生命被赋予那刻,就无法挽回地注定了,注定了你的一切。走出冰屋,来到一边在永恒之光下流淌不息的意识的河川,每一滴水都是鲜活的生命。这时想起,生命的过程是否是另一种水循环?逆流而上,却发现这条河流绵延。这是一条天河,我永远也达不到终点。 “嘿!” 背后有人在呼唤我?转过身去,却只见到模糊的人影。那是我?是过去的我?未来的我?是存在的我?不存在的我?那是我?冰在融化,幻梦在崩塌,冰屋在崩塌,水流在干涸……倏地感觉手心中有一股热流,额上满是热汗,眼前景象仍是虚无和现实的交织。双腿渐渐恢复力量,但是支撑着的手臂已然麻木。这才发觉又回到窗前。 倚在窗上,这次,离外面的世界更近了,离里面的世界更近了,但这种距离永远不能量化。看向寻常的,现在又不寻常了。曾经有一段时光,甚至希望在遥远的 2011年,失手坠落的自己真的坠落了。消失在自己的过往,如同月下漂浮的烟霭,毕竟是毫不痛苦的。如今却太迟了,已经开启了一趟前往终结的旅途,路途中想都不敢想那一无所有的大限已至的宁静。但那也会是可怕的,就像在迷失的 2021,痛苦地徘徊在现实和虚幻,拿一本书连接起精神和肉体,不真实的世界,敌对的世界,变得和善。如果我不曾活过,周围的一切或许都一如现在一样运作。非也!至少我也改变了身边的人吧。活着,生命灿烂。 指着天空,什么也没有指向。把窗户开到最大,把音响上的悠扬的爵士乐开到最大!疾风!暴风!狂风!暴雪!暴雨!吹走我的灵魂!洗涤我的灵魂!救赎我的灵魂!我渴望飞向远方,飞向平流层,飞出大气层,飞到外太阳系,飞出宇宙的边界!我的精神没有边界!放下自己的肉体,放下沉重的一切。在梦里我什么都能放下,在醒时我什么都能放下! 但是梦醒了便不记得梦中事了,但是入梦了就不记得真实了。不过梦也无需要一种理由吧。 所以睡一觉,回到那个冰屋,什么都有了。 所以醒一日,把冰屋放在心里,什么都有了。

2022/12/21
articleCard.readMore

RECAP2022: 流星雨

献给 2022,和那错过的英仙座流星雨。 什么时候才能在纷繁中寻回真正的自我?—— 可惜已经失去了光阴。险些忘记了今年是何年。 但是至少 2022 要在我的一生中留下痕迹。 久立窗前,空洞的夜空。清爽的山泉洗涤了我阴郁中沉沦的灵魂。在父亲上高中的地方,绿茵场上,苦苦等待流星雨。据说8月13号夜里有英仙座流星雨。同一片夜空,同一个世界,不同的时空。那也是我将要作别故乡的一天。 夜间,清凉的风,在这群山环抱的村落。几天前,或在山泉水侧垂钓,或在县城夜市赶集。体态轻盈,行走如飞,来去匆匆。渐渐懂得《田园》中的乐趣,那跳动的音符正是我山行的步伐。只可惜那谢公已不再,也固然寻不到那登山的木鞋。村落的小巷邂逅多年前见过的人,停留在虚掩的院门,看那猫偷食吊挂的腌鱼。在停电的日子里,远山的轮廓在星空中已经变得模糊,但记忆却变得清晰。烧烤的熏香从千里之外,从数月之前游荡入我的鼻腔、口腔,刺激我的味蕾。 或许是在汽车上,看着长江三峡的万吨货轮,看碧云蓝天,看千里江山。而在火车上,望着远去的平原,山谷,那幽静的小径和喧闹的都市,水库、太阳能板和干涸的小河。空阔的世界!耳机中流淌出来的柴可夫斯基第一钢琴协奏曲,远行的这现代的人类奇迹!自然奇迹! 雨水击打在窗上,夕阳斜照在车站的一角,层云化身灰暗的三角,指向遥远的天际。一切都如同离开上海的那天,从台风逃离。突然告知朋友取消明日的骑车旅行。熟悉的路径,就和今年二月一样,也和去年二月一样。走过蜿蜒的林间小道,沿着黄浦江,直上陆家嘴。世博源的火锅?不小心用公筷尝了一口滚烫的牛丸,却惹你们一笑。冒泡的热汤,温暖,深情厚谊在其中升华。下次当然会更小心!不知不觉竟与过去的你对话,却不知道如今同学群却陷入沉寂。毕竟大家都要踏上远行的征途,何日是归期? 几日前,还在剪辑毕业视频。远程指导录制、演唱,摆好动作,调整姿态。却不记得之前是自招、是中考。雷雨的那天,几乎彻夜未眠,次日早要靠那浓茶。出考场的时候,头晕目眩。 好在完全没受影响,甚至超常发挥。收到录取通知的那天,正从故乡赶来。计划未来,却不知道初进校园,陌生的地方,甚至有些不习惯。从社恐,到如今向外迈出了几步。新的一年要自信。 夜间逛校园,远望天鹅湖对岸,确认是否有其他人。雨中漫步,把外套当成雨衣。或许只有我们会傻到这样做。离谱。 在机房停课学习 OI,一周更五篇博客。逐渐从疫情复苏的国家,重复的网课。今年三月,突然接到通知回家,却是欣喜?自以为是认为可以很好利用时间。谁知开启了摸鱼的生活。也罢,不断调整,欣赏古典音乐,在阳春三月的雨中用最大的音量播放那异国他乡,来自纽约的爵士乐。又忆起时代广场霓虹灯中的雪,可久远的回忆已经变得朦胧。和同学拓展关系,丝毫不觉得临近分别为时过晚。确实有些遗憾吧。但是返校之后,在清晨、黄昏的网约车上,每一种天空,每一个日子。也曾和司机交谈,走近那些不一样的人生。Life is tough. 沉溺在试卷中,却清醒地看见明天——我离未来最近的一段时光。和你在网上打卡拍摄天空,可惜现在不知道你身处何方。 十二月的天空,有些许凄清。准备英才计划,还是刚刚得知 NOIP 一等的消息。临近圣诞,或许在某个平行宇宙,在永恒的过去的 2021,还有一些人在夜间的校园长跑。或许望着校门外的灯火,会在寒风中拿出手机,播放那一曲 Merry Christmas,会大声祝福:”马上 2022 了,一切会更好的!“ 2021对我是痛苦的,但我确实有所得。 幸运的是,如今也应该会有这样的声音。Merry Christmas。 回到山间,记忆中的气味逼近。是外婆。是外公夜间骑摩托回到山上的家,留下外婆给我们送行。是远处已经远到看不见的灯火亮起,亲朋好友在农闲时刻欢聚。是院中的雏鸡、猪羊。想起那个在农家小院里,看着天空,乱按计算器的日子。 躺在乡间某个高中的足球场上,嗅着草香,意识游离。等待流星雨,痛恨没把相机带在身边。一颗,两颗,三颗……但只见得满天星斗,似乎有什么东西闪过,若隐若无。那天或许没有流星雨,但眼前的镜像模糊了,变成了一团,渐渐看不真切了。 醒来时在上海,2022年,12月,17日。 不知如何评价这一年,但是我将要改变了,但是我确实改变了。希望明年不要再把 2023 错认成 2022。我存在过,每一年我都存在过。Carpe diem。 2023会更好。 Restart. 至少还会有流星雨。

2022/12/17
articleCard.readMore

清夜

月起晚风拂,萤光碎火流;不知明朝复今夕。 月升,微光照过灰色的十二月的天空。十二月了?可我的意识还停留在那个蝉鸣的六月。 门外有孩童在嬉戏;远方的地铁列车飞驰,发出空气摩擦的空洞声响;窗外昏黄的路灯仍然用橙黄的光将树染成怀旧的颜色——这一切,像四月。池塘还是静穆,那轮明月依旧悬在明朗的夜空。 九天之上或许有天宫?都说天上一日,地上十年。或许仙人也总是逍遥。也能想象,在远方的故乡,农夫或许刚刚回到土屋之中,嗅着空气中带着的泥土的香味,在冉冉升起的炊烟中休憩。鸡犬相闻,微风吹过树梢,远山的巨大影子和繁星点点……蜿蜒的山路,还有车辆往来。引擎发出那种低沉的连续的声响。山脚下,家家户户的灯亮起,家家户户的灯熄灭…… 但那都不是我。记忆跟不上遗忘的步伐,时间的乡愁却见渐变得浓烈。我甚至记不起2021年。多少的过去在时光中淡去,但是那些人和事却在遗忘中永恒。留不住的。 月光皎洁,星海荡漾,旋转、流动。高压线塔的轮廓依稀可辨,却和梦的幻境交织结合。久远的夏日,我曾望着远山,那山的轮廓模糊。或许那是 2013,或许是 2015,和早已消散在时光里的故人在山间漫步。甚至认为这是前世的记忆。熟悉的面容在时间里溶解。 一颗明星划过星野,远处市中心的灯光依旧灿烂。在回乡的火车上,我看到粉红色、橙红色渐变到深邃的夜的蓝。远行的高铁列车上,我欣赏着昼的关闭,夜的开启。群山、平原、天空、城市、乡村都以让人眼花缭乱的速度划过眼前,连成一线。我要离了我的故乡了。 那是在深秋,操场跑道铺了一层金黄色的树叶的地毯。夜空清澈,一群学生在长跑。深红色跑道、浅黄色的教学楼、深棕色的长椅和一排绿色的松树,在黑夜中却显出一个颜色。校门外的灯火被绿树的高墙阻隔。但透过升腾着的吸气、呼气的雾霭,少年的歌声嘹亮。如今或许看不到这样的学生了?当年,这样的夜晚却不啻那一天。或许很快,我也终说不去那些人的姓名。 错乱的时空。 月升,水汽中迷蒙的窗,映着我的面容。给我开一壶良药,复活我逝去的时光。我的过去已死,如果再来,我想我仍会这样选择。 也罢,往事如烟。 后记:分了两天写,所以有衔接不连贯(

2022/12/12
articleCard.readMore

割点 Tarjan 算法

最近学习图论,写篇题解记录一下。 定义 对于一个无向图,如果把一个点删除后这个图的极大连通分量数增加了,那么这个点就是这个图的割点(又称割顶)。 这篇博客主要介绍,Tarjan 算法用于求 割点。 割点 Tarjan 算法,记录 节点访问时间戳 dfn,节点能够回溯到的最早的点的时间戳 low。 对于某一点: 如果这个点是根节点,且有两个以上与它相连的连通分量,那这个点就是割点。 如果某个点后继是一个连通分量,而这个点不是根节点,那这个点是割点。 第一种情况 我们需要记录根节点 fa,在遍历的时候,如果重复访问到了 fa,说明找到了 fa 下面的一个连通分量。 第二种情况 设当前点 s,对于访问的下一个节点 y: 如果 low[y] >= dfn[s],说明这个点下面有一个连通分量。 注:这里类似于 Tarjan 求 SCC 时,我们所做的 min(low[s],dfn[y])。 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void tarjan(int s, int fa){ dfn[s] = low[s] = ++cc; int child = 0; for(int i = head[s]; i!=-1; i=NDS[i].next){ int y = NDS[i].to; if(!dfn[y]){ tarjan(y,fa); low[s] = min(low[s], low[y]); // 回溯后更新 if(low[y]>=dfn[s] && s != fa) // 情况 2 cut[s] = 1; if(s==fa) // 情况 1 计数 child++; } low[s] = min(low[s], dfn[y]); } if(child>=2&&s==fa){ cut[s] = 1; // 情况 1 } }

2022/12/4
articleCard.readMore

P3147 USACO16OPEN 262144 P 题解

DP 系列。 题面 看题,Luogu 合并相邻的相同数字,变成数字加一。求获得的最大值。 思考 最初想到的是基础的区间 DP,不做解释: 1 2 3 4 5 6 7 8 9 10 11 12 13 long long ans = 0; for(int len = 2; len<=N; len++){ for(int i = 1; i+len-1<=N; i++){ int y = i+len-1; for(int k = i; k<y; k++){ if(DP[i][k] == DP[k+1][y]){ DP[i][y] = max(DP[i][y], DP[i][k] + 1); } } ans = max(ans, DP[i][y]); } } cout << ans << endl; 但是 $ 2 \leq n \leq 262144 $ ,显然会 MLE。 优化 借鉴思路,我们发现可以使用类似倍增的方法去做。 用状态 f[i][j] 表示 合成之后结果为 i,右端点为 j 的区间的左端点位置,如果 值为 0 即 不可行。 因为题目要找两个相邻相等的区间,合成。有: 1 2 3 f[i][j] = f[i-1][f[i-1][j]]; 把 f[i][j] 拆分成两个能合成为 i-1 的区间 即 1 2 3 4 5 f[i-1][j] |------<i-1>-----|----<i-1>-----| j f[i-1][f[i-1][j]] 如果 f[i-1][j] 或 f[i-1][f[i-1][j]] 不成立,f[i][j] 就不成立,即转移为 0 那如何表示结果? 记录 ans,如果 f[i][j] 可行,就更新 ans。因为 i 递增,所以不需要 max 操作。 得到 1 2 3 4 5 6 7 8 9 10 for(int i =2; i<=58; i++){ for(int j = 1; j<=N; j++){ if(!DP[i][j]){ DP[i][j] = DP[i-1][DP[i-1][j]]; } if(DP[i][j]){ ans = i; } } } 注意我们倍增合并,所以 log2262144+40=58log_2{262144} + 40 = 58log2​262144+40=58 是可能获得的最大值。 初始化 显然不合并是可行的,所以在输入的时候,初始化 1 2 3 4 5 for(int i = 1; i<=N; i++){ int in; cin >> in; DP[in][i] = i+1; } 关于 i+1:为了避免区间重复,我们 f[i][j] 表示的区间是左闭右开区间,所以右端点是 i+1 小结 这道题是区间 DP 状态优化,DP 学习之路漫漫,还需要多加练习。

2022/11/24
articleCard.readMore

P3354 Riv 河流 题解

最近在练树形 DP,正好看到 这一道 虚标的紫题,但本蒟蒻不会写,想出来了便记录一下 题面 & 思考 先看题面,一颗有根树,选定 k 个节点作为 ”伐木场“,求运送木料最小费用。注意木料费用是 dis * wood。 最开始想到简单的树形背包,状态转移方程: 1 f[i][k] = min(f[j][s] + cost, f[i][k]); 但是注意到,如果某个后代节点如果是伐木场,cost 不需要计算,所以状态中还需要存储后代的伐木场情况。 但是后代中锯木厂不止一个。考虑到树有唯一的父亲,且同一深度祖先唯一,可以记录最近的伐木场祖先,作为状态的一部分。 有 f[i][j][k] 即 i 节点 最近的伐木场祖先为 j,后代(不算自己)有 k 个是伐木场。 但是由于 f 自己也可能是伐木场,转移方程不同,需要分类讨论,于是改成:f[i][j][k][0/1] 其中 0 代表自己不是伐木场, 1 表示自己是伐木场。 状态转移方程 因为我们需要枚举祖先,在 DFS 时需要记录 Fa 数组: 1 2 3 DFS 开始时:fa[++tot] = x; 结束时:tot--; 简单记录祖先 stack。 回溯后,对于当前节点 x 和 子节点 y 每个祖先 ff: 1 2 3 4 先对每个 k 赋初值,对于每种伐木场个数 l: f[x][ff][l][0] += f[y][ff][0][0]; --> 当前节点不是伐木场,子节点 y 最近伐木场为 l,对任意 f,赋最大值,即 子结点中没有伐木场。 f[x][ff][l][1] += f[y][x][0][0]; --> 当前节点是伐木场,子节点 y 最近伐木场为 当前节点,对任意 f,赋最大值,即 子结点中没有伐木场。 然后就是树形背包: 1 2 3 4 f[x][ff][l][0] = min(f[x][ff][l][0], f[x][ff][l-s][0] + f[y][ff][s][0]); --> 当前节点不是伐木场,对 y 节点分配 s 个伐木场个数 f[x][ff][l][1] = min(f[x][ff][l][0], f[x][ff][l-s][1] + f[y][x][s][0]); --> 当前节点是伐木场,对 y 节点分配 s 个伐木场个数 唯一的不同是 y 节点最近祖先为 x 注意在枚举 l 时,由于是01背包,需要倒过来枚举,不然状态计算会叠加。(很容易理解) 做完了?好像还差一个 cost! 考虑到 祖先节点 ff cost 的贡献,因为是 当前节点 W 乘以 到 ff 的总距离! 需要计算总距离,维护 dep 数组,即当前节点到根节点距离,即可!很容易理解。ff 到 x 的距离就是 dep[x] - dep[ff] 对于当前节点 x 每一个祖先 ff: 1 2 3 4 5 6 7 8 if(l>=1){ --> 因为 l 需要 -1 ,要分类讨论。 f[x][ff][l][0] = min(f[x][ff][l][0] + W[x] * (dep[x]-dep[ff]), f[x][ff][l][1]); 合并 0 和 1,因为回溯之后,1 的状态不再被使用,便于下一步计算。 -1 是因为上文 f[x][ff][l][1] = min(f[x][ff][l][0], f[x][ff][l-s][1] + f[y][x][s][0]); 时,s+l-s = l 但是当前节点也是伐木场,所以状态更新是 l+1 的,要 -1 获取正确结果 }else{ l = 0 时,当前节点不可能为伐木场,直接添加到 ff 增加的贡献 f[x][ff][l][0] += W[x] * (dep[x]-dep[ff]); } 这里再来聊一聊合并。为了便于讨论,上文背包转移的时候,我们没有考虑 y 的 1 的情况,而是在每次 y 回溯时 合并 0 和 1。这有点类似于滚动数组?回溯后 0 不再表示之前的意义,而是我们最初设计的状态:i 节点 最近的伐木场祖先为 j,后代(或自己)有 k 个是伐木场! 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 #include <cmath> #include <cstdio> #include <iostream> #include <cstring> using namespace std; struct Node { int to, next, d; } NDS[201]; int head[201], vis[201]; int cnt = 0; long long W[201]; int tot = 0; void add(int a, int b, int d) { NDS[cnt].to = b; NDS[cnt].next = head[a]; NDS[cnt].d = d; head[a] = cnt++; } int fa[201]; long long f[201][201][52][2]; long long dep[201]; long long n, k; void dp(int x) { fa[++tot] = x; vis[x] = 1; for (int i = head[x]; i != -1; i = NDS[i].next) { int y = NDS[i].to; if (vis[y]) continue; dep[y] = dep[x] + NDS[i].d; dp(y); for (int j = tot; j >= 1; j--) { int ff = fa[j]; for (int l = k; l >= 0; l--) { f[x][ff][l][0] += f[y][ff][0][0]; f[x][ff][l][1] += f[y][x][0][0]; for(int s = l; s>=0; s--){ f[x][ff][l][0] = min(f[x][ff][l][0], f[x][ff][l-s][0] + f[y][ff][s][0]); f[x][ff][l][1] = min(f[x][ff][l][1], f[x][ff][l-s][1] + f[y][x][s][0]); } } } } for (int j = 1; j <= tot; j++) { int ff = fa[j]; for (int l = k; l >= 0; l--) { if(l>=1){ f[x][ff][l][0] = min(f[x][ff][l][0] + W[x] * (dep[x]-dep[ff]), f[x][ff][l-1][1]); }else{ f[x][ff][l][0] += W[x] * (dep[x]-dep[ff]); } // cout << x << " "<<ff << " "<< l << " " << f[x][ff][l][0] << " " << endl; } } // cout << dep[x] << endl; tot--; } int main() { // Type your code here memset(head, -1, sizeof(head)); cin >> n >> k; for (int i = 1; i <= n; i++) { int w, v, d; cin >> w >> v >> d; W[i] = w; add(i, v, d); add(v, i, d); // 链式前向星 } dp(0); cout << f[0][0][k][0] << endl; // 输出结果,注意是 合并后,所以是 0 return 0; }

2022/11/23
articleCard.readMore

马拉车算法

最近在学习马拉车算法,简单记录一下心得。(如有疏漏,请指出 先看 模板题 ,要求最长回文串的长度。 首先思考朴素算法,显然是 O(n3)O(n^3)O(n3) ,无法通过。而马拉车算法能将时间复杂度优化到 O(n)O(n)O(n)。 性质 对于一个回文字符串,必然有一个对称中心,在对称中心两侧的部分均全等。 一个回文字符串对称之后得到的一定也是回文字符串 即 aba x aba 但是对于奇数、偶数长度的回文字符串,这个对称中心可能是字符,也可能在两个字符中间。 如:ab | ba, a b a 所以考虑,在两个字符中间都插入隔板 #,即 abba 变成 #a#b#b#a#。原长度为 n 的字符串,增加 n+1 隔板,长度变成 2n+1 必然是奇数,方便统计。 思路 马拉车算法,即记录一直最长回文子串区间,对朴素算法进行优化。 因为是朴素算法两侧向外拓展,隔板对判断回文无影响。p[i] 数组存储以 str[i] 为对称中心的回文字符串半径长度。半径长度中计算了隔板个数,所以得到的就是回文字符串长度。 1 2 3 4 5 6 7 8 9 10 11 for(int i = 0, l = 0, r = -1;i<s2.size(); i++){ int k = (i>r)? 1 : min(p[l+r-i], r-i+1); while(0 <= i-k && i+k<s2.size() && s2[i-k]==s2[i+k]){ k++; } p[i] = --k; // 注意最后一次循环会对加上一个 1 if(i+k>r){ l = i-k; r = i+k; } } 先记录 i,枚举每个对称中心,记录 l 和 r 即目前最长回文字符串的左右端点。k 则是目前半径长度。 算法主体就是朴素算法,向左右两端拓展。 考虑优化。如果i处在一个回文子串中,因为对称性,可以得到与i对称的点j的最长回文串长度。因为i不断增加,对称的点的坐标一定小于i即已经更新过。 由于上文推断的性质,回文子串可以对称得到。注意单个字符也可以考虑成一个回文子串。所以 k 可以从 之前的 p[j] 开始计算。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 (设 x 表示 [l,r] 对称中心,j 就是 i 关于 x 的对称点) 1. 案例1 l r #a#b#b#a# ^ ^ ^ j x i 2. 案例2 l r #a#b#a#b#a#b#a# ^ ^ ^ j x i 手推方便理解 然后考虑如何计算 j,因为中点坐标公式,得到 l+r2=i+j2=mid\frac{l+r}{2} = \frac{i+j}{2} = mid2l+r​=2i+j​=mid ,得到 j=l+r−ij = l+r-ij=l+r−i。 但是因为确定区间,且偶数情况存在。所以还应判断 j 是否在区间内。 而如果不在区间内,很显然应该从1开始枚举。 所以得到: 1 int k = (i>r)? 1 : min(p[l+r-i], r-i+1); 每次更新 l r 区间长度即可。 AC Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <cstdio> #include <iostream> #include <string> using namespace std; int p[110000001]; int main() { // Type your code here string s1; cin >> s1; string s2; s2.resize(s1.size()*2+4); s2[0] = '~'; s2[1] = '#'; for(int i = 0, j=2; i<s1.size(); i++, j+=2){ s2[j] = s1[i]; s2[j+1] = '#'; } int ans = 0; for(int i = 0, l = 0, r = -1;i<s2.size(); i++){ int k = (i>r)? 1 : min(p[l+r-i], r-i+1); while(0 <= i-k && i+k<s2.size() && s2[i-k]==s2[i+k]){ k++; } k--; p[i] = k; if(i+k>r){ l = i-k; r = i+k; } ans = max(ans,p[i]); } cout << ans << endl; return 0; } 小结 马拉车算法实用且容易理解,但熟练掌握还需要练习。 作业 | 最长双回文串

2022/11/20
articleCard.readMore

夜雨

太久没更博客了,别来无恙 2020.11.16 日夜雨有感,18日记 夜雨一直下,下在这小城的一隅。 从广场走出,漆黑一片,不远处却是车水马龙,仿佛隔了一个世界。雨伞下,近乎看不清的霓虹渐明了。但此刻我只见到微光下如丝的雨和它有节奏地击打在伞面上的声音。 这是冬日的雨,路旁伫立,晶莹的雨点散在大衣的绒毛上,形成了彩色的泪珠。我知道这和去年此刻的景一样。伫立,长叹,冉冉升起的白色雾霭是对这喧嚣的叛逆。 风起,微寒,但雨下如同泪涟涟,不知何时终了。 上了车,向车后望去,移动的灯火与车流、人流,在夜的深邃中,形成红色的流动的丝绸飘带。车窗外的世界总是呈现怀旧的昏黄,而这生活的千篇一律着实让人麻木。在自己的热爱织成的茧中窒息,在对旧日的追忆中迷失。西西弗斯式地在单调中沉沦,无可救药,我亲手造成了自我的慢性自杀。 脑海中涌动的昨日,如同白纸,毫无意义。微寒,放松,我似乎又找回了去年此刻的心境。身体却是轻盈,御风而行,泠然善也。我知道过去成就今日,而此刻我仍然陷入迷茫却清醒的叠加态,是循环往复的轮回的孤独。 窗外的雨一如去年、前年、渐渐被忘却的过往,落地就无法挽回的过往。那些,我已经找不到了,于是只能叹息。这是人生最大的 BUG,过去的就不能再来,经历就是一种失去。 人生。 改变? 一切尽在车窗外夜雨的缄默里。 而我。 我还是我吗? 这些话,何止今日说起过呢? 换一种思维方式,换一种生活,换一种人生,突破过去的茧,重获新生。 人生不再千篇一律。真正的自我解放。 但夜雨不会停。因为没有办法让它停下来。 但天亮了就会是新的一天。

2022/11/18
articleCard.readMore

层雾

花非花,雾非雾。夜半来,天明去。来如春梦几多时,去似朝云无觅处。 今晨,上海下着一场大雨,天色阴沉。窗上蒙了一层水汽,更远处便是层层雾霭之下的昔日无比熟悉的河川景致。 出门。雨敲击在雨伞上发出有节奏的声音,四周也有些许走着的行人。但这些都离我太远了。雨带给我的只有那本就属于我的失意。 回想 2020 到现在,时光匆匆,几乎不能感知时光的流逝。但它终究还是溜走了!而且似乎在一瞬间!旧日的一幕幕,如今还在疾速流去的时光之河。我想让它停下来,是的一定要停下来。反复思索,琢磨,这样在低沉中的循环是否是生命的本质,诘问我们是否真的有能力改变我们的未来,改变命运的走向。或许掌握仅仅是自我麻醉。我们或许从未掌控过什么。也许我们仅仅是回忆,也许我们从未存在,也许我们存在过,也许眼前的一切都是虚幻。没有人知道答案。 层雾遮盖住眼前的道路,看向四周的人。我总觉得陌生,而无所适从,总觉得不安。毕竟在层雾中的人,找不到方向。我好像从来都没有得到内心深处的满足,从未有过,在短暂的逝去的岁月里。未来也不会有吧?毕竟我们没有能力决定我们的来去,甚至连自己最基本的属性都不能决定,没有能力。我们的开场都是天命。 到了。站立在灯光微弱的走廊里,四周是一片空虚。时间太早了,没有什么人。 人生是这样吗?逝去的岁月是这样吗? “花非花,雾非雾。夜半来,天明去。来如春梦几多时,去似朝云无觅处。” 也许是我沉溺在对无意义的追索中,或者仅仅是过去的痛苦太愉快了,又或者是我已经被单调麻醉?生活最初的样子? 忽然来了两个孩童,蹦起来按下电灯开关。 眼前一片明朗,就像昨日的阳光。 ”也许明天也是这样。“ 谁知道呢?但是 C’est la vie. 层雾,……

2022/11/11
articleCard.readMore

从愚人节玩笑到真的玩笑(bushi): 浅谈 lsnotes

离了个大谱 (不过这个想法挺好的 想法 愚人节本来是开玩笑的,结果发现,挺有用。笑死 前几天和朋友讨论,说要给每个目录加个提示语,ls pwd cd 这些命令时显示出来。 e.g.: 1 2 3 4 $ ls The place where I code! --- Demo OI Playground Projects 这样就解决了,目录那么多,自己甚至都忘了这个干啥了的情况。当然,还有很多其他的用法,比如可以在 .lsnotes 中显示 build 方式。 概况 lsnotes 是个水项目,目前只支持纯文本显示(未来会加上 Markdown 解析,短时间内先鸽了。 就目前的代码量而言,小学生都会写… 后续 MrWillCom 又做了一个更强的 lsnotes 即 lnn。 这个项目功能简单,但实用,未来不怎么会维护了。

2022/4/15
articleCard.readMore

题解 纪念品分组

快要 CSP-S2 了,复习一下一些算法(弄文化课弄了好久了,很多东西都要忘了。。。 读题 题目链接: Luogu P1094 看题,把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品。看样子,应该是贪心。每次取一个大的,一个小的,就可以保证了。如果大的小的组合起来,超过了最大值,就只取大的。 解题 很容易就可以写出程序。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <algorithm> #include <cstdio> #include <iostream> using namespace std; int ar[30001]; int main() { int n, w; cin >> w >> n; for (int i = 0; i < n; i++) cin >> ar[i]; sort(ar, ar + n); int ans = 0; int l = 0; int r = n - 1; while (r >= l) { if (ar[l] + ar[r] <= w) { l++; r--; ans++; } else { r--; ans++; } } cout << ans; return 0; } 证明 可以参考这个 结语 能力有限,如有疏漏,请谅解并补充,谢谢。

2021/10/1
articleCard.readMore

题解 导弹拦截

快要 CSP-S2 了,复习一下一些算法(弄文化课弄了好久了,很多东西都要忘了。。。 读题 题目链接: Luogu P1020 数据是这样的:389 207 155 300 299 170 158 65 推一推,我们发现,389 300 299 170 158 65是第一问的答案;在 155->300的时候,要使用另外一颗炮弹了,故最少应该配备两套。 在草稿纸上面推一推,不难发现,这道题的两小问,就是让你求一个不上升序列长度和一个上升序列长度。 预备知识 在求这两个东西之前,需要先学习STL中的两个函数:lower_bound upper_bound。 其中, lower_bound 是求序列中第一个大于等于某个数的数;upper_bound 是求序列中第一个大于某个数的数。这两个函数返回的是指针。 它们使用的前提是 序列是有序的。 以lower_bound为例,具体用法类似: 1 2 3 int a[100]; // ... lower_bound(a, a+len, x); // 前两个参数传入的都是指针 这一函数默认是求升序序列中符合条件的数,如果要改为降序序列,则需要一个 cmp 函数,这一点类似于 sort。比如: 1 2 3 int a[100]; // ... lower_bound(a, a+len, x, std::greater<int>()); // 前两个参数传入的都是指针 解题 我的 AC 代码。 本题有两种算法,O(n)O(n)O(n),O(nlogn)O(nlogn)O(nlogn)。这里只讲后者。 不上升序列 我们用数组d1当作栈来存储它。 遍历导弹高度,把栈顶元素和高度比较: 若 ai<=dlena_i <= d_lenai​<=dl​en,此时aia_iai​是符合要求的,直接入栈。 若 ai>dlena_i > d_lenai​>dl​en,此时aia_iai​把栈内第一个小于它的覆盖掉。这里说一下,能够覆盖它是因为我们不需要再访问它的值了。在测试数据中,此后几次都会进行这一操作,如果仅仅取这几个数据,最长不上升子序列长度仍然正确; 取所有数据,几次操作之后,就会执行操作1,结果仍然正确。 上升序列 和不上升序列一样,只不过把 upper_bound 改为了 lower_bound,因为会出现两个相同高度的导弹的情况,这两个导弹仅仅需要同一的炮弹去拦截。 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <algorithm> #include <iostream> using namespace std; int ARR[100001]; int n = 0; int d1[100001]; int c1 = 0; int d2[100001]; int c2 = 0; int main() { while (cin >> ARR[n]) n++; d1[0] = ARR[0]; d2[0] = ARR[0]; for (int i = 1; i < n; i++) { if (ARR[i] <= d1[c1]) d1[++c1] = ARR[i]; else { int j = upper_bound(d1, d1 + c1, ARR[i], greater<int>()) - d1; d1[j] = ARR[i]; } if (ARR[i] > d2[c2]) d2[++c2] = ARR[i]; else { int j = lower_bound(d2, d2 + c2, ARR[i]) - d2; d2[j] = ARR[i]; } } cout << c1 + 1 << endl << c2 + 1 << endl; return 0; } 结语 能力有限,如有疏漏,请谅解并补充,谢谢。

2021/10/1
articleCard.readMore

如何高效使用搜索引擎

这篇文章已经在 GitHub 开源了。 最近遇到一些人不太会用搜索引擎,就写了这篇文章。。。有不对的地方,或者要补充的地方希望大家踊跃评论、PR。 目录 简介 认识搜索引擎 搜索引擎的代表 如何高效检索 言简 意骇 高级技巧 一举多得 让搜索引擎为你做减法 我只想看这一个网站怎么办 限定文件格式 限定网址 限定标题 告诉搜索引擎搜索的是作品 告诉搜索引擎不要拆开关键词 推荐阅读 特别鸣谢 参考资料 简介 最近我经常遇到一些同学,经常跑来问我一些很明显在搜索引擎上面就可以搜到的问题。我问他们为什么不去网上搜,却发现其实他们搜过,只是效果不好:有些人直接把一整个问句打上去了,还有人漏关键字。这些都是他们没有掌握搜索引擎使用的精髓。所以,我写了这个教程,帮助解决搜索引擎的使用问题。 认识搜索引擎 我这里说的搜索引擎是指网络搜索引擎。下面给出维基百科中的定义: 网络搜索引擎(英语:web search engine)是设计在万维网上进行搜索,意思是指自动从万维网搜集特定的信息,提供给用户进行查询的系统。 搜索引擎的工作原理大致可以分为搜集信息、整理信息和接受查询。为了使文章简单,更深入的知识我在这里就不展开了,本文以如何使用为主。 搜索引擎的代表 百度 必应 搜狗 360搜索 谷歌 Yandex 还有学术型搜索引擎: 百度学术 谷歌学术 如何高效检索 我认为,高效检索只需要注意:言简、意骇 言简 言简,顾名思义,就是让你的搜索尽可能更简单。在搜索的时候,应该对问题提取关键词。比如,我想要知道高锰酸钾制取氧气的文字表达式是什么时,我仅仅需要写高锰酸钾制取氧气 文字表达式 即可;同样的,在查询怎么写检讨书时,甚至只需搜索检讨书;在想知道《将进酒》是谁写的,只用查询将进酒 作者。如果不确定要搜索的内容名称,应该做更少的准确限定,换为更零散的关键词。如果是英文,则应去除复数和第三人称复数。虽然某些搜索引擎在进行查询的时候会自动去除掉 「xxx的xxx」这种词汇和标点符号,但在搜索时还是应该尽量减少他们的使用。也尽可能不要出现 「如何」「怎样」这些疑问词,更不需要和搜索引擎讲礼貌——不要出现类似「请问寒假什么时候放假?」而是写成「寒假放假时间」。 意骇 意骇,就是把你的搜索描述的尽可能完备。不要一昧地追求简单,在有些情况下还是需要给出限定的:比如,在搜索苹果时,如果你指的是水果的苹果,那为了提升效率,最好写苹果 水果;同理,想要搜索苹果公司,则应该写苹果 公司,这可以简化为苹果公司。如果不进行限定,有可能搜索结果第一页都会被此关键词的其他意思所充满,在搜寻时,就会降低效率。 更加高级的限定方法,请见高级技巧。 高级技巧 一举多得 如果我在搜索的时候,想同时获得多个关键词的结果,我可以使用 |,即“或”。注意:用|分隔关键词的时候,一定要加上空格,|必须要是半角的,举个例子:东京 | 塔。 让搜索引擎为你做减法 如果我在搜索的时候,不想获得某个关键词的结果,我可以使用 -,即“减”。注意:用-,一定要在之前加上空格,举个例子:苹果 -水果。 我只想看这一个网站怎么办 如果我只想获得某个网站的结果,可以在整个搜索之前或之后加上 site:xxx网站,比如:site:blog.aeilot.top 数码。 限定文件格式 如果我只想搜索一种格式的文件,可以在整个搜索之前或之后加上 filetype:xxx网站,比如:filetype:pdf 物理课本。不指定文件类型搜索文件时,可以使用filetype:all。 限定网址 如果我想让我的搜索结果的网址都包含某一字断,可以加上 inurl:xxx,比如:inurl:pan PPT模版,就可以找到网址带pan的所有相关结果。 限定标题 如果我想让我的搜索结果的标题都包含某一字断,可以加上 intitle:xxx,比如:intitle:免费 PPT模版,就可以找到标题带免费的所有相关结果。 告诉搜索引擎搜索的是作品 如果我搜索的是作品,如文学作品、艺术作品,可以加上书名号,比如:《星际穿越》。 告诉搜索引擎不要拆开关键词 如果我不想要拆开搜索的关键词,可以加上引号,比如:“九年级化学“ 推荐阅读 知乎 - 如何高效地使用搜索引擎 特别鸣谢 MrWillCom 他对我的创作进行了指导。 Cathy Aeilot 她启发了我写这份教程。 参考资料 网络搜索引擎 – 维基百科

2021/8/27
articleCard.readMore

用 GitHub Actions 格式化 C/C++ 代码

我的 ProblemSet 项目,每次都 Format 太麻烦了,需要一个自动化 Format 的功能。利用 GitHub Actions,即可实现。 GitHub Actions GitHub Actions 是 GitHub 推出的持续集成服务,最近不要钱了,用(白嫖)的人就多起来了。 代码 直接上代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 name: "Check Clang Format" on: [push, pull_request] jobs: format: name: "Run Clang Format" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: "Install clang-format" run: | sudo apt-get update sudo apt-get install clang-format-10 - name: "Format Codes" run: clang-format-10 -style=file -i */*/*.cpp - name: Push changes uses: actions-go/push@v1 with: author-name: Clang Format Bot commit-message: Run clang-format 后记 如果大家有什么改进的好方法,可以在下方评论!

2021/8/20
articleCard.readMore

四季的天空

使用单反拍摄,Louis Aeilot 版权所有,所有图片都未经过后期处理,仅经过压缩。 拍摄用时1年,就是每次看到了都会去拍一张。

2021/7/19
articleCard.readMore

洛谷 7 月月赛 Div.2 总结

昨天(7/14)参加了洛谷的 7 月月赛,感觉题目挺新颖的,就是数据有点。。。 比赛链接:这里 我的代码在 这里 A 乍一看好像没思路,但是想一想,其实很简单,就是会有几种情况: 0个空格 全是数字的话,需要判断一下 A. 两者完全相同 B. 非A,情况 A 是可以输出 Yes 的。 1个空格 这一种情况,从原理上分析,“选择一个有正整数的格子和一个与之相邻的空格子,将正整数移到那个空格子中”,可以得出,其实只要顺时针转一圈,初始和最终状态顺序相同,就符合条件。所以,只需要做三次判断即可,简单粗暴(在座的各位大佬要是有高端方法可以通知一下🙇)。 2、3、4个空格 这几个情况,经过分析会发现,不管如何,都是满足条件的。 所以,这样分析下来,很简单就 AC 了,拿到 100 分! B 这道题。。。无语了。。。测试数据通过了,结果测评数据每次都卡一个,万恶的捆绑测试。。。最后得不了 100 分了。。。 这道题最开始想的是贪心算法,排序,但是会超时,就改了一下:开两个数组,不管顺序,只管符号,放进去。这样做基本上不超过 10ms。 原理就是,计算 +正数 +负数 *正数 *负数 出现的个数,进行排列,最后计算结果。 C 因为学业原因,离开了几个小时,回来了之后都没时间做了。。。有点思路,但没写完。。。 其实,可以根据数第一次出现的位置判断从左、右数的位置,最后进行排列即可。 D 看了一眼就懒得写。 小结 等题解吧!感觉题目很有意思,都是些需要仔细思考的题目。(奈何我太弱了。。。太弱小了!!!

2021/7/15
articleCard.readMore

题解 最近公共祖先 (LCA)

好久没刷题了,复习一下:LCA。 题目详情 题目很简单,就是求多叉树两个点的最近公共祖先。 链接: 洛谷 P3379 LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先。 ———来自百度百科 图中,4 和 3 的 LCA 就是 1。 解题 最简单的方法 (暴力) 这种方法数据一大就会TLE。 原理很简单,让两个数一个一个向上走,直到两个数相遇。第一次相遇就是他们的 LCA。 很简单,就不赘述了,直接上代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 #include <cmath> #include <cstdio> #include <iostream> #include <vector> using namespace std; #define MAX 500000 vector<int> tree[MAX];// 以邻接表形式存储 int dep[MAX]; int fas[MAX]; namespace M1 { void dfs(int x, int fa) { if (fa != -1) { dep[x] = dep[fa] + 1; } fas[x] = fa; for (int i = 0; i < tree[x].size(); i++) { if (fas[tree[x].at(i)] == -2) M1::dfs(tree[x].at(i), x); } } int solve(int a, int b) { while (1) { if (a == b) { return a; } else if (fas[a] == fas[b]) { return fas[a]; } else if (fas[b] == a) { return a; } else if (fas[a] == b) { return b; } int da = dep[a], db = dep[b]; int delta = abs(da - db); if (da > db) { for (int i = 0; i < delta; i++) { a = fas[a]; da = dep[a]; } } else if (da < db) { for (int i = 0; i < delta; i++) { b = fas[b]; db = dep[b]; } } else { a = fas[a]; da = dep[a]; } } return -1; } }// namespace M1 bool first = true; int LCA(int a, int b, int r) { if (first) { M1::dfs(r, -1); first = false; } int res; res = M1::solve(a, b); return res; } int main(int argc, char *argv[]) { int m, n, s; cin >> m >> n >> s; for (int i = 0; i < MAX; i++) { dep[i] = 0; fas[i] = -2; } for (int i = 1; i < n; i++) { int x, y; cin >> x >> y; tree[x].push_back(y); tree[y].push_back(x); } dep[s] = 0; fas[s] = -1; for (int i = 0; i < m; i++) { int a, b; cin >> a >> b; int res = LCA(a, b, s); cout << res << endl; } return 0; } 注意这道题目的数据输入,x y 表示x 结点和 y 结点之间有一条直接连接的边(数据保证可以构成树)。 所以需要用邻接表的形式,表示多叉树。 倍增法 这个算法是对上面暴力算法的优化。这个算法的时间复杂度为O(nlogn)O(nlogn)O(nlogn),已经可以满足大部分的需求。 上述算法中,一步一步跳太慢了,这里我们事先做好标记,就可以每次 2i2^i2i 步向上跳,一直到相遇。 代码中有较为详细的注释: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 #include <cmath> #include <cstdio> #include <iostream> #include <vector> using namespace std; #define MAX 500001 // 本题最大数据规模 #define MUL_MAX 22 vector<int> tree[MAX]; // 以邻接表形式存储 int dep[MAX]; // 预处理存储节点深度 int fas[MAX][MUL_MAX]; // 存储 x 节点上面第 2^i 次方个祖先 bool first = true; // 记录预处理是否结束 int lg2(int x) { return log(x) / log(2) + 1; // 无理数计算记得加上 1 来避免误差 } // 手动写了一个函数,来求 log2(x) void dfs(int x, int fa) { // x 是当前节点,fa 是它的父节点 if (fa != -1) { dep[x] = dep[fa] + 1; // x 的深度就是它的父节点加一,这很好理解 } fas[x][0] = fa; // x 节点的第一个父节点是 fa for (int i = 1; (1 << i) <= dep[x]; i++) { // 循环直至 2^i 大于当前节点深度,即完成当前节点到树根的所有可跳转到的节点的预处理工作 fas[x][i] = fas[fas[x][i - 1]][i - 1]; // 这一步是算法的精髓 // 得到状态转移方程,动态规划计算 // 意思是x的2^i祖先等于x的2^(i-1)祖先的2^(i-1)祖先 } for (int i = 0; i < tree[x].size(); i++) { if (tree[x].at(i) != fa) dfs(tree[x].at(i), x); // 邻接表存储当前节点所有相连的节点,只要节点不是它的父节点,即节点是它的子节点,就进行下一步递归 } } // 深度优先搜索来预处理一下 int solve(int a, int b) { if (dep[b] > dep[a]) swap(a, b); // 确保 a 的深度更深,避免冗余的判断 while (dep[a] > dep[b]) { a = fas[a][lg2(dep[a] - dep[b]) - 1]; // a 向上跳,跳至两节点同级 } if (a == b) return a; // 若此时两节点相遇,就可以直接返回。否则两节点还需再次向上跳。 for (int i = lg2(dep[a]); i >= 0; i--) { if (fas[a][i] != fas[b][i]) { a = fas[a][i]; b = fas[b][i]; } } // 从可跳到的最高处向下枚举,得到 LCA return fas[a][0]; // 返回答案 } int LCA(int a, int b, int r) { if (first) { dep[r] = 0; fas[r][0] = -1; dfs(r, -1); first = false; } int res; res = solve(a, b); return res; } int main(int argc, char *argv[]) { int m, n, s; cin >> m >> n >> s; for (int i = 0; i < MAX; i++) { dep[i] = 0; for (int j = 0; j < MUL_MAX; j++) fas[i][j] = -2; } // 数组初始化 for (int i = 1; i < n; i++) { int x, y; cin >> x >> y; tree[x].push_back(y); tree[y].push_back(x); // 邻接表存入数据 } for (int i = 0; i < m; i++) { int a, b; cin >> a >> b; int res = LCA(a, b, s); cout << res << endl; } return 0; } 其实还可以预处理出一个 lg 数组,避免对数计算,大家可以自己去尝试,会有一定时间优化效果。 无法理解倍增?这里有个 经典资料 其他方法 实际上还有更快的方法求这道题的答案。倍增算法已经可以满足需求,就不再往下写了。 Tarjan ST 算法 大家有兴趣可以去尝试一下。 后记 这里放上两种列出算法的评分。 暴力 倍增

2021/4/24
articleCard.readMore

用简单的物理方法证明牛顿莱布尼茨公式

前几天经过苦思冥想,想出来了一种简单的证明方法,现在来简单分享一下。 关于牛顿莱布尼茨公式 即微积分基本定理。 ∫abf(x)dx=F(b)−F(a)=F(x)∣ab\int_a^b f(x)dx = F(b) - F(a) = F(x)\bigg|_a^b∫ab​f(x)dx=F(b)−F(a)=F(x)∣∣∣∣∣​ab​ 其中,F(x)F(x)F(x) 为 f(x)f(x)f(x) 原函数。 构思 有初中物理知识可以知道,在 v-t 图像中,面积就是位移,两点间面积之差就是时间差的积分。 所以很容易证明出这一定理。 证明 所以 v-t 函数的原函数就是 s(t) 函数,所以 [a,b] 区间内的位移就是 s(t)∣abs(t)\bigg|_a^bs(t)∣∣∣∣∣​ab​ 而上文已经得出 v(t) 函数在 [a,b] 区间的积分也指的是位移。 所以很容易得出要证明的结论。 总结 本人仅是业余爱好进行学习,若有不足,请指正。

2020/12/25
articleCard.readMore

简评荣耀手环6

前几天买了个 荣耀手环6,简单点评点评。 优点 屏幕在一般的手环里算是比较大的,比较全面屏,颜值也挺高的。 续航把类似自动运动监测、心率检测、压力检测之类的打开了之后都有一个星期的续航。 离线支付宝、NFC真的很方便。 etc 不足 表盘,说实在的,真得没有小米的好看,还不支持自定义,希望以后能适配。话说。。。这设计者怕不是喝了假酒(bushi)。 非华为系手机用不了一些特别功能,比如心脏健康什么的,不过可以破解,自行搜索。 24小时血氧检测这个功能是不支持的。 期望 第一次买华为系的产品(不过现在荣耀已经分离了),感觉还挺好。 就是希望官方能够加强自定义功能和对于非华为手机,特别是苹果手机的适配。 总结 这一款产品还是非常值得买的,当然,这里不建议苹果用户购买NFC版本,不然很多功能无法使用。 价格:标准版 249,NFC 289

2020/12/25
articleCard.readMore

海上生明月,天涯共此时。

使用单反拍摄,Louis Aeilot 版权所有。镜头不够。。。。。。

2020/10/1
articleCard.readMore

我为什么重新拿出了 iPod

我有一个 iPod Shuffle,已经吃灰多年了。。。最近重新拿出来用了。 事情的起因 我订阅了 Apple Music,挺不错的,只是在 Phone,Mac 这些设备上,不管多么优美悦耳的音乐都成了使用设备的背景音乐。。。无法让人专心听完一首歌曲。我们似乎已经忘记之前没有这些东西时,沉静在一首歌曲中的感受了。 我拿出了这款 iPod Shuffle,有点掉色,却不影响使用。感谢,它让我找回了之前发现一首好歌、听完一首好歌的激动、欣喜与感动!闭上眼睛,静下心来,享受着属于你自己的余音绕梁的乐曲。 音乐来源 有人要问了,你的乐曲从哪里来的?众所周知,现在所有的平台都有 DRM… 我购买了网易云音乐包,8元一个月,然后使用这个 Doge。 结语 实际上 iPod 还有一个好处,就是小巧 方便带到学校去,好藏。

2020/9/11
articleCard.readMore

Swift 中的 SharedPreferance —— UserDefaults

从 Android 开发又最终回到 iOS 了,好多东西都不知道。最近一直有需求要用一个类似 Android 的 SharedPreferance 的东西。找了一下资料,来总结一下。 它是什么 不会吧?不会还有人不知道 SharedPreferance 吧??? SharedPreferance 是一种轻量级的 Android 储存API, 用于储存简单的数据,数据多了就不如其他方式高效了。 iOS 中,起同样作用的东西,叫 UserDefaults。 这两者都以 key-value 的形式存储。 使用场景 简单数据 简单数据 简单数据 复杂数据建议使用 SQLite 或者 Core Data,不建议作死。。。 Quick Start 直接上代码,里面注释我都写好了。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 let defaults = UserDefaults.standard // 获取全局的 UserDefaults defaults.set(Int.max, forKey: "int") // 存储 defaults.integer(forKey: "int") // 读取 defaults.set(true, forKey: "bool") defaults.bool(forKey: "bool") defaults.set(Double.infinity, forKey: "double") defaults.double(forKey: "double") defaults.set(Float.infinity, forKey: "float") defaults.float(forKey: "float") 默认值 Float, Int, Double 的默认值都是 0;Bool 的默认值是 false。 更多 大家可以多在 Playgrounds 里面试试,还可以看看 Apple Developer Documentation。

2020/8/24
articleCard.readMore

凝视那一轮明月

随便乱写的,,,要拿去参加一个小比赛。。。 初夏,深夜,我却还在熬夜赶作业。 夜里,恍惚着,偶然向窗外望了望。多完美的一轮明月啊! 凝视这一轮明月,它明亮,照白了月边稀疏的云;它洁净,仿佛世间没有什么比它跟洁白如雪;它深邃,好像有不尽的秘密。周围繁星点点,如同月亮的伙伴,与她共欢笑。明朗的夜空,月亮和繁星点缀,让这个夜晚,显得十分安静祥和。 我不禁陷入无尽的想象。月儿啊!这孤独的夜,你有着星星的陪伴,与我不同!月儿啊!夜深人静时,你怎么还没入睡?是否和我一样,还在努力奋斗?月儿啊!一个个夜晚,你是否感觉有点烦闷?…… 想着想着,我突然想到:身处闹市区,是如何见到这样的明月的?这夜空明朗的,让人惊奇,我从未见过。这夜空,不应该满是雾霾、尘埃吗? 我回想起,好多年前,那也是一个这样的的夜晚,我和朋友们在路口乘凉,可能才刚上小学。 抬眼望去,一片灰蒙蒙的天,几乎看不清什么月亮,更别提星星了。那时候,上海的明朗的夜晚并不是天天有。 “这月儿,今天晚上又躲起来了,看不清了。”一旁的嘉豪一边向天上凝视,一边说。但是,最终他还是未能知晓月儿的真面目。 “环境污染太严重了,那些工厂、车辆,人类生活影响到了环境。”我说着,仿佛看到了远处郊区的几座大工厂,烟还在不断上升到大气中。 嘉豪打了个哈欠。现在已经是夜深人静时,远处的卡车的声音,很清楚,又很微弱。老师讲过,有些卡车用的油不符合标准,排放出来很是污染环境。我们站在这路口,似乎还能闻到汽油发出的一种难闻的味道。 这路口,昏黄的路灯还在亮着,高楼大厦还在发着光。“书上说,大部分的电力还是来自不清洁能源。”喜爱读书的嘉豪说。一个晚上,这灯火通明的闹市区,不知要浪费多少电呢。 夜深了,我记不起后面说了什么,想了什么。 恍惚间,我又陷入了沉思。啊,我的月儿!你看起来有些孤独!没有星星的陪伴,你还好吗!啊,我的月儿!你听见这卡车的声音,问道汽油的味道了吗?啊,我的月儿!这样一个夜晚,你却躲了起来,是有什么秘密吗? …… 夜晚,有些凉,我被冻醒,已经凌晨二三点了吧。 我再次举头凝视天边的月亮。诶?月亮怎么又躲起来了?我望向桌上杂乱摆放的作业。诶?我的作业怎么已经写完了!原来,一切,是梦。作业写完后,我太累了,就在书桌上睡着了。 我的月亮,答应我,以后不要再躲起来了?我都能见到你和星星,在无数个静寂而孤独的夜!答应我,让我梦想成真,好吗? 将来,我再次凝视那一轮明月……

2020/8/23
articleCard.readMore

用 GitHub Actions 部署 Hexo 博客

最近有一个朋友找我,说她弄了一个 Hexo 博客,想做 GitHub Actions 自动部署,奈何不会弄,只好让我帮忙。 GitHub Actions GitHub Actions 是 GitHub 推出的持续集成服务,最近不要钱了,用(白嫖)的人就多起来了。 代码 话不多说,直接上代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 name: "Hexo Blog Builder" on: [push, pull_request] jobs: build: name: "Hexo Blog Build" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: fetch-depth: 1 - uses: actions/setup-node@v1 with: node-version: '12' - name: Install Hexo run: npm install -g hexo - name: Install Dependencies run: npm install - name: Clean Previous Build run: rm -rf docs - name: Hexo Clean run: hexo clean - name: Generate New Build run: hexo generate - name: Move docs/ run: mv public docs - name: Publish run: | mkdir -p ~/.ssh/ echo "${{ secrets.KEY }}" > ~/.ssh/id_rsa.pub chmod 600 ~/.ssh/id_rsa.pub ssh-keyscan github.com >> ~/.ssh/known_hosts git config --global user.name "Hexo Deploy Bot" git config --global user.email "nobody@nobody.nobody" git config --global core.quotepath false git add --all git commit -m "Hexo Blog Build" git push origin master 本 Action 需要你的 ssh 公钥,也就是 id_rsa.pub 存在项目设置中的 Secrets 内。 TL;DR 具体实现很简单,用 Hexo 自带生成器生成到 public 目录,把 public 目录改名为 docs。最后 push 到项目里。 push 使用 SSH Key,实现免密码。 在 GitHub Pages 设置中,需要把 Source 改为 docs 目录。 后记 如果大家有什么改进的好方法,可以在下方评论!

2020/8/22
articleCard.readMore

迟来的日志 - WWDC 2020 奖学金

今年 6 月份,因为疫情的影响,WWDC改为线上,之前的奖学金重命名为 Swift Student Challenge。 我老早就有参加这一活动的打算,只是一直没能实现,也没有达到要求。今年大胆尝试了一会,虽然成绩不理想,但还是收获了许多。 我今年的项目在 aeilot/WWDC2020。 Overview 今年我的项目使用了 SwiftUI 和 SpriteKit。我做了一个 2D 的跑酷类游戏,内容是关于 COVID19 的。 整体开发下来,多亏了 Apple Document,里面的文档很详细,还有示例,👍。 当然开发中遇到的几个问题,我也是在 Apple Developer Forums 和 Stack Overflow 解决的。具体链接就不写了,社区很活跃,10分钟就有人回答了。 只是开发太赶,只有不到一个星期,决定参加都花了几天,🤦‍♀️。。。所以最后成果像一个半成品。。。 Future 关于明年的 WWDC,我想我是一定会去参加的!最好早点准备,加油!等着我的好消息!

2020/8/19
articleCard.readMore

vcpkg - 方便的 C/C++ 库管理器

最近在做一个大型的 C++ 项目 ── Albumist。它使用 Qt,需要用到很多类似 sqlite3、exiv2、libcurl 之类的库。第三方库管理似乎成了问题。 支持 git 的都可以使用 git submodule 来管理,但是还有少部分是不支持的,或者是二进制的,比如 sqlite3。这就要我们手动去下载,手动去更新,好生麻烦。 vcpkg 我一直想要一个类似 npm pip 一样的东西,把依赖写在文件里面,然后直接 install 即可。 经过搜索,我发现了微软的一个项目 vcpkg。官方定义它为 “C++ Library Manager for Windows, Linux, and MacOS”,简单翻译一下就是 “支持 Windows, Linux 和 macOS 的 C++ 库管理器”。 在 Arch Linux 上面,安装它并不复杂,只需要:sudo pacman -S vcpkg-git 即可。其他系统没有尝试过,跟着它的 README 也很方便安装。 “清单” 功能 在项目根目录创建一个 vcpkg.json, 然后 vcpkg install。这一功能就是“清单”功能。它正好是我想要的,可是却暂时处在 Beta 阶段,不过也无关紧要。 要启用“清单”功能,在执行命令时,需要接参数 --feature-flags = manifests。 清单大概长这样: 1 2 3 4 5 6 7 8 { "name": "<name of your project>", "version-string": "<version of your project>", "dependencies": [ "abseil", "boost" ] } 很方便,也很快捷。 不足 比起这样一个纯粹的管理器,我更希望获得类似 Java 的 Gradle 的体验。如果 CMake 能加入类似功能,体验一定能够翻倍,快捷方便且无需第三方软件。 后记 — 2020 08 15 更新 又停止使用这个东西了,Windows 上面需要 MSVC。。。

2020/8/13
articleCard.readMore

vimrc 配置指南

Vim 即 Vi Improved,它的前身是 Vi。它是一个十分强大的编辑器,优点如下: 不需要鼠标,纯键盘 Linux 系统预装 键盘命令肌肉记忆之后,效率非常高 但是,它的配置许许多多,让人难以记住。我正好要在新电脑上配置它,故写此文。 为什么不用别人现成的? 自己的配置更顺手,自己更熟悉。 了解 Vim Script,可以自己造插件 etc. 不会 Vim 怎么办 啊这…… 🤣 你可以试着在命令行输入 vimtutor。 vimrc 的位置 本篇文章以新安装的 vim 为例。Vim 的配置文件叫做 vimrc。在 Mac、Linux 等系统上,位于 ~/.vimrc。在 Windows 系统中,它叫做 _vimrc,但是同样位于 Home 目录中。 全局的配置,在 Mac、Linux 等系统上,位于 /etc/vimrc。在 Windows 系统上,它储存在 Vim 安装目录,同样叫做 vimrc。 配置 一个什么也没有配置的 Vim,打开可能是这样的: 下面各配置,你可以添加自己想要的。以下所有配置都可以在命令模式输入,临时启用或关闭。 基本 1 2 3 4 5 6 7 8 9 set nocompatible " 不使用 Vi 兼容模式 filetype plugin on " 检测文件类型,加载插件 syntax on " 开启语法高亮 set showmode " 显示当前模式 set showcmd " 在底部显示命令 set mouse=a " 启用鼠标,不建议开启 set encoding=utf-8 set t_Co=256 filetype indent on " 根据文件类型,不同缩进 缩进 1 2 3 4 5 set autoindent " 自动缩进 set tabstop=4 " tab占4个空格 set shiftwidth=4 " 在文本上按下>>(增加一级缩进)、<<(取消一级缩进)或者==(取消全部缩进)时,每一级的空格数。 set expandtab " tab自动转为空格 set softtabstop=2 " tab转为多少空格 界面 1 2 3 4 5 6 7 8 9 set number " 显示行号 set relativenumber " 显示光标所在行当前行号,其他都显示为相对于当前行的行号 set cursorline " 当前行高亮 colorscheme default " 设置颜色主题为 default,颜色主题储存在 Home 目录的 .vim/colors 文件夹,Windows 下叫做 vimfiles/colors set wrap " 设置多于行宽的文本自动分拆为多行显示,反之: set nowrap set linebreak " 遇到特殊的符号才折行 set laststatus=2 " 是否显示状态栏。0 不显示,1 只在多窗口时显示,2 显示。 set ruler " 状态栏显示光标位置 set showmatch " 高亮括号 搜索 1 2 3 set hlsearch " 高亮搜索结果 set incsearch " 搜索输入时,即时跳转 set ignorecase " 忽略大小写 更多 Vim 配置不止这些,我只介绍了一些常用的。Vim Script 值得学习,学完了还可以自己开发插件。 题外话 - 插件 插件管理,Vim 虽然新增了自带的,但我还是很推荐 Vim-Plug

2020/7/26
articleCard.readMore

NextCloud - DIY NAS 解决方案

前言 我之前给家中的服务器做了一个 WebDAV 功能,带有不堪入目的 UI 和难以使用的功能。而且配置起来并不简单。一直想要改进,但是却一直没时间。最近有空了,便开始寻找替代品。 查了几下 GitHub,找到了一个标星 10k+ 的项目 —— NextCloud。了解了一下,NextCloud 是一个拥有 全平台客户端,支持 WebDAV,而且 插件化,可以 多用户 使用的私有云存储网盘项目。不仅如此,它还支持共享、版本控制、团队协作等功能。插件化让它拥有了类似 Markdown 在线编辑,Draw-io 在线编辑,显示 RAW 文件的功能。 而且,我发现它支持 Docker,这无疑简化了我们配置的步骤。 那么,我们开始吧! Docker 配置 Docker 安装很简单,为了安装快速,你可以参考清华大学开源镜像站给出的 文档。如果你已经安装了 Docker, 那么可以忽略这一步。 更换镜像也是让你更快体验的必不可少的一步,修改 /etc/docker/daemon.json 文件 1 2 3 4 5 6 7 8 9 10 11 { "registry-mirrors" : [ "http://registry.docker-cn.com", "http://docker.mirrors.ustc.edu.cn", "http://hub-mirror.c.163.com" ], "insecure-registries" : [ "registry.docker-cn.com", "docker.mirrors.ustc.edu.cn" ] } 安装 NextCloud 运行如下命令即可: 1 2 3 4 5 sudo docker run -d \ --name nextcloud \ -p 8000:80 \ -v <数据储存位置>:/var/www/html \ nextcloud 如果遇到如下问题: 1 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? 可以运行: 1 2 systemctl daemon-reload systemctl restart docker.service 配置 配置这一部分很简单,不用解释了。 选择数据库时,使用量小可以选择 SQLite,但是并不推荐。 结语 NextCloud 还是非常稳定的,基本配置完之后不会遇到什么问题。而且原生支持中文,只需要在设置中设置一下就可以了。 我主要用它储存我的照片,摄影还有一些不需要经常查看的文件。由于自己服务器性能不错,用起来很流畅,完全没必要买现成的,硬盘不够再买一个即可。

2020/7/23
articleCard.readMore

sudo shutdown -r now

你可能会惊奇地发现博客上面以前的文章全不见了。最近我对我博客进行了一次大清扫。 tl;dr 前几天,我突然发现自己的博客上面全是水文(以前就知道,懒得弄),心里总觉得过不去。所以,我下定决心,准备重新来过。这种感觉很好,当_posts目录空无一物时,我的心也释然了。 之前我所有的文章,要么是抄袭的,要么是很水的那种。在这里,我承诺,以后不再会有这种不可饶恕的情况发生了。这样做我自己心里也总是想着缺点什么。幸幸苦苦修改的自定义hexo主题(没错,我把 hexo-theme-cactus 修改了很多,支持了 RSS,还弄了些 UI 改进,配置了 Valine.js,etc.),结果呢?上面全是水文!?这…… 那么之前的文章都去哪里了呢?我并没有删除,而是把它们放置在了 Draft 目录下面,当然,你们看不到。手动狗头 让我们重新认识对方,运行一次sudo shutdown -r now!

2020/7/22
articleCard.readMore