<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>MituFun&apos;s Blog</title><description>MituFun 的博客</description><link>https://blog.mitufun.top/</link><language>zh_CN</language><item><title>PIP 问题</title><link>https://blog.mitufun.top/posts/pip/pip-%E9%97%AE%E9%A2%98/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/pip/pip-%E9%97%AE%E9%A2%98/</guid><description>一个简单的几何的问题</description><pubDate>Wed, 01 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::note&lt;/p&gt;
&lt;p&gt;下文内容来自本人其他地方的博客，并对其进行了部分修改。&lt;/p&gt;
&lt;p&gt;本文以下内容已经经过极多组随机数据与某篇论文（太久了，实在想不起来了）所提供std进行对拍，并未出现任何错误，可信度较高。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h2&gt;题目&lt;/h2&gt;
&lt;p&gt;在网上看到了这样的一道题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;顺时针给出 $n$ 边形的 $n$ 个顶点，再给出一个点 $(x,y)$，判断该点是否在该多边形内部。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:::tip&lt;/p&gt;
&lt;p&gt;对于此题我已制作题目，可以自行测试：https://www.luogu.com.cn/problem/U244855&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h2&gt;想法&lt;/h2&gt;
&lt;p&gt;引入一种方法：射线法。&lt;/p&gt;
&lt;p&gt;我们任意拉一条以 $(x,y)$ 为顶点的射线，如果射线与多边形的交点个数为奇数，则在多边形内部；反之，在多边形外部。&lt;/p&gt;
&lt;p&gt;证明：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;0x14kjba.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我们随意画出了一个多边形。由于多边形的边将一张图分为了“内部”和“外部”，因此每穿过一条边就相当于从“内部”走到了“外部”，或者反之。那对于在内部的点，首先会经过一条边到达外部，再经历进入出去循环，即奇数。如果在外部，不需要出去，就直接可以经历进入出去的循环，即偶数。&lt;/p&gt;
&lt;p&gt;这个进入出去的路径，就是随意拉的一条射线。&lt;/p&gt;
&lt;h3&gt;特例&lt;/h3&gt;
&lt;p&gt;但是我们会碰到几个特殊情况&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;case1：引出的射线与多边形的顶点相交&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1jss4goz.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;例如上图，如果不特判的话，如果遇到精度误差，可能会导致少算几个交点，导致答案出错&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;case2：引出的射线与多边形某条边重合&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;o71xtn5m.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;同样如果不特判同样也会出现问题&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于以上两种情况的解决方案是重新换一条射线，其他的方法懒得想，次数也不会很多，常数级别的，不会影响运行效率&lt;/p&gt;
&lt;h2&gt;代码实现&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#include&amp;lt;iostream&amp;gt;
#include&amp;lt;climits&amp;gt;
#include&amp;lt;cstring&amp;gt;
#include&amp;lt;cstdio&amp;gt;
#include&amp;lt;cmath&amp;gt;
using namespace std;

#define db double

const double eps = 1e-5;
const int maxn = 2010;

int n, q;
struct point {
	db x, y;
	point() {}
	point(db xx, db yy) {
		x = xx, y = yy;
	}
};
point pt[maxn];
struct line {
	db k, b; // 斜率与截距
	db sx, ex; // 线段在 [sx, ex] 之间
	line() {}
	line(db kk, db bb, db ssx, db eex) {
		k = kk, b = bb;
		sx = ssx, ex = eex;
	}
};
line ln[maxn];
line ray;

// 获得连接 pt1 与 pt2 的线段信息
line getLine(point pt1, point pt2) {
	line tmp;
	tmp.k = (pt1.y - pt2.y) / (pt1.x - pt2.x);
	tmp.b = pt1.y - tmp.k * pt1.x;
	tmp.sx = pt1.x;
	tmp.ex = pt2.x;
	return tmp;
}

// 判断两个 double 类型是否相等
bool equal(db a, db b) {
	return fabs(a - b) &amp;lt; eps;
}

// 判断 p 是否被 l 穿过
bool passPoint(line l, point p) {
	if (equal(l.k * p.x + l.b, p.y)) {
		if (l.sx &amp;gt; l.ex) {
			swap(l.sx, l.ex);
		}
		if (l.sx &amp;lt;= p.x &amp;amp;&amp;amp; p.x &amp;lt;= l.ex) {
			return 1;
		}
	}
	return 0;
}

// 判断 ray 是否合规
bool checkERROR() {
	for (int i = 1; i &amp;lt;= n; i++) {
		if (passPoint(ray, pt[i])) {
			return 1;
		}
	}
	for (int i = 1; i &amp;lt;= n; i++) {
		if (equal(ln[i].k, ray.k) &amp;amp;&amp;amp; equal(ln[i].b, ray.b)) {
			return 1;
		}
	}
	return 0;
}

// 判断 ln1 和 ln2 是否相交
bool checkInter(line ln1, line ln2) {
	point tmp;
	tmp.x = (ln2.b - ln1.b) / (ln1.k - ln2.k);
	tmp.y = ln1.k * tmp.x + ln1.b;
	return passPoint(ln1, tmp) &amp;amp;&amp;amp; passPoint(ln2, tmp);
}
bool check(point a) {
	point tmp;
	do {
		tmp.x = rand() % 200;
		tmp.y = rand() % 200;
		ray = getLine(a, tmp);
		ray.ex = INT_MAX;
	} while (checkERROR());

	int cnt = 0;
	for (int i = 1; i &amp;lt;= n; i++) {
		if (checkInter(ln[i], ray)) {
			cnt++;
		}
	}
	return cnt % 2;
}

int main() {
	cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; q;
	for (int i = 1; i &amp;lt;= n; i++) {
		cin &amp;gt;&amp;gt; pt[i].x &amp;gt;&amp;gt; pt[i].y;
	}

	pt[0] = pt[n];
	for (int i = 1; i &amp;lt;= n; i++) { // 建出多边形的边
		point pt1 = pt[i - 1];
		point pt2 = pt[i];
		ln[i] = getLine(pt1, pt2);
	}

	while (q--) {
		point p;
		cin &amp;gt;&amp;gt; p.x &amp;gt;&amp;gt; p.y;
		if (check(p)) {
			cout &amp;lt;&amp;lt; &quot;Yes&quot; &amp;lt;&amp;lt; endl;
		}
		else {
			cout &amp;lt;&amp;lt; &quot;No&quot; &amp;lt;&amp;lt; endl;
		}
	}
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>基于模拟退火的线性回归模型计算方法</title><link>https://blog.mitufun.top/posts/%E5%9F%BA%E4%BA%8E%E6%A8%A1%E6%8B%9F%E9%80%80%E7%81%AB%E7%9A%84%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92%E6%A8%A1%E5%9E%8B%E8%AE%A1%E7%AE%97%E6%96%B9%E6%B3%95/%E5%9F%BA%E4%BA%8E%E6%A8%A1%E6%8B%9F%E9%80%80%E7%81%AB%E7%9A%84%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92%E6%A8%A1%E5%9E%8B%E8%AE%A1%E7%AE%97%E6%96%B9%E6%B3%95/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/%E5%9F%BA%E4%BA%8E%E6%A8%A1%E6%8B%9F%E9%80%80%E7%81%AB%E7%9A%84%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92%E6%A8%A1%E5%9E%8B%E8%AE%A1%E7%AE%97%E6%96%B9%E6%B3%95/%E5%9F%BA%E4%BA%8E%E6%A8%A1%E6%8B%9F%E9%80%80%E7%81%AB%E7%9A%84%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92%E6%A8%A1%E5%9E%8B%E8%AE%A1%E7%AE%97%E6%96%B9%E6%B3%95/</guid><description>奇思妙想</description><pubDate>Wed, 04 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::warning&lt;/p&gt;
&lt;p&gt;下文内容并没有进行正确性验证，纯属娱乐。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h2&gt;奇思妙想&lt;/h2&gt;
&lt;p&gt;上课的时候突然想到了这种奇妙方法，但是适用性并不普遍，大抵只适用于低次的拟合函数。——后来发现好像还挺普遍的&lt;/p&gt;
&lt;p&gt;但是感觉挺有趣的，顺便温习一下之前所学。&lt;/p&gt;
&lt;p&gt;观察到对于一组样本数据 $(x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n)$ 进行建模。若当前拟合函数为 $y=ax+b$ 则其均方误差（MSE）被定义为：&lt;/p&gt;
&lt;p&gt;$$E(a, b) = \frac{1}{n} \sum_{i=1}^{n} (y_i - (ax_i + b))^2$$&lt;/p&gt;
&lt;p&gt;对于目标拟合函数，则要求 $E(a,b)$ 取得最小值。&lt;/p&gt;
&lt;p&gt;故此，不难想到对于未知单调性且貌似找不到什么规律的函数求其最值，较好的方法便是使用模拟退火跑 $a$ 和 $b$。对于模拟退火的学习笔记可以看我两年前写的 &lt;a href=&quot;https://www.luogu.com.cn/article/m91jin71&quot;&gt;洛谷博客&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;然后套式子就行。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include&amp;lt;iostream&amp;gt;
#include&amp;lt;cmath&amp;gt;
#include&amp;lt;cstdio&amp;gt;
#include&amp;lt;iomanip&amp;gt;
#include&amp;lt;cstdlib&amp;gt;
using namespace std;

const int maxn = 1010;

int n;
struct Point {
    double x, y;
} p[maxn];

double pow2(double x) { return x * x; }

double MSE(double a, double b) {
    double res = 0;
    for (int i = 1; i &amp;lt;= n; i++) {
        double pred = a * p[i].x + b;
        res += pow2(p[i].y - pred);
    }
    return res / n;
}

double a_ans, b_ans, best_cost;

void SA() {
    double a = a_ans, b = b_ans;
    double T = 1000, Tmin = 1e-6, delta = 0.98;
    double cur_cost = MSE(a, b);

    while (T &amp;gt; Tmin) {
        double a_new = a + (rand() * 2.0 - RAND_MAX) / RAND_MAX * T;
        double b_new = b + (rand() * 2.0 - RAND_MAX) / RAND_MAX * T;
        double new_cost = MSE(a_new, b_new);

        if (new_cost &amp;lt; cur_cost || exp((cur_cost - new_cost) / T) * RAND_MAX &amp;gt; rand()) {
            a = a_new, b = b_new;
            cur_cost = new_cost;
            if (cur_cost &amp;lt; best_cost) {
                a_ans = a;
                b_ans = b;
                best_cost = cur_cost;
            }
        }

        T *= delta;
    }
}

int main() {
    cin &amp;gt;&amp;gt; n;
    for (int i = 1; i &amp;lt;= n; i++) {
        cin &amp;gt;&amp;gt; p[i].x &amp;gt;&amp;gt; p[i].y;
    }

    a_ans = 0, b_ans = 0;
    best_cost = MSE(a_ans, b_ans);

    SA();SA();SA();SA();SA();SA(); //想准一点就多退几次

    cout &amp;lt;&amp;lt; fixed &amp;lt;&amp;lt; setprecision(5) &amp;lt;&amp;lt; &quot;a = &quot; &amp;lt;&amp;lt; a_ans &amp;lt;&amp;lt; &quot;, b = &quot; &amp;lt;&amp;lt; b_ans &amp;lt;&amp;lt; endl;
    return 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;更进一步&lt;/h2&gt;
&lt;p&gt;:::note&lt;/p&gt;
&lt;p&gt;以下记于 2025.6.13&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h3&gt;具体实现&lt;/h3&gt;
&lt;p&gt;此外，容易发现此方法具有极强的扩展性。对于任意次的拟合函数只需要退火时多退几个参数即可。即使这会导致结果大概率错误，但是貌似对于“无限次回归”没有通解的存在，普遍使用神经网络等算法进行实现，其难度对比此非属同一量级。&lt;/p&gt;
&lt;p&gt;以下进一步进行说明。&lt;/p&gt;
&lt;p&gt;对于一拟合函数：&lt;/p&gt;
&lt;p&gt;$$\hat{y}(x) = \sum_{k=0}^{N} \text{index}_k x^k$$&lt;/p&gt;
&lt;p&gt;其目标函数可被定义为：&lt;/p&gt;
&lt;p&gt;$$\text{Loss}(\text{index})=\sum^m_{i-1}(y_i-\hat{y}(x_i))^2$$
容易写出代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include&amp;lt;iostream&amp;gt;
#include&amp;lt;cmath&amp;gt;
#include&amp;lt;cstdio&amp;gt;
#include&amp;lt;iomanip&amp;gt;
#include&amp;lt;cstdlib&amp;gt;
using namespace std;

const int maxn = 1010;
const int maxd = 20;

int n, deg;
struct Point {
    double x, y;
} p[maxn];

double pow2(double x) { return x * x; }

double index[maxd + 1]; 
double best_index[maxd + 1];
double best_cost;

double val(double x) {
    double res = 0, x_pow = 1;
    for (int i = 0; i &amp;lt;= deg; i++) {
        res += index[i] * x_pow;
        x_pow *= x;
    }
    return res;
}

double MSE() {
    double res = 0;
    for (int i = 1; i &amp;lt;= n; i++) {
        res += pow2(p[i].y - val(p[i].x));
    }
    return res / n;
}

void SA() {
    double T = 1000, Tmin = 1e-6, delta = 0.98;
    double cur_cost = MSE();

    while (T &amp;gt; Tmin) {
        double new_index[maxd + 1];
        for (int i = 0; i &amp;lt;= deg; i++) {
            new_index[i] = index[i] + (rand() * 2.0 - RAND_MAX) / RAND_MAX * T;
        }

        for (int i = 0; i &amp;lt;= deg; i++) index[i] = new_index[i];
        double new_cost = MSE();

        if (new_cost &amp;lt; cur_cost || exp((cur_cost - new_cost) / T) * RAND_MAX &amp;gt; rand()) {
            cur_cost = new_cost;
            if (cur_cost &amp;lt; best_cost) {
                for (int i = 0; i &amp;lt;= deg; i++) best_index[i] = index[i];
                best_cost = cur_cost;
            }
        } else {
            for (int i = 0; i &amp;lt;= deg; i++) index[i] = best_index[i];
        }

        T *= delta;
    }
}

int main() {
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; deg; // n 对应点数，deg 对应多项式次数
    for (int i = 1; i &amp;lt;= n; i++) {
        cin &amp;gt;&amp;gt; p[i].x &amp;gt;&amp;gt; p[i].y;
    }

    for (int i = 0; i &amp;lt;= deg; i++) index[i] = best_index[i] = 0;
    best_cost = MSE();

    SA();SA();SA();SA();SA();SA();SA();SA();

    cout &amp;lt;&amp;lt; fixed &amp;lt;&amp;lt; setprecision(5);
    for (int i = 0; i &amp;lt;= deg; i++) {
        cout &amp;lt;&amp;lt; &quot;a[&quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot;] = &quot; &amp;lt;&amp;lt; best_index[i] &amp;lt;&amp;lt; endl;
    }

    return 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;复杂度分析&lt;/h3&gt;
&lt;p&gt;约定 $n$ 为数据点数，$d$ 为多项式次数&lt;/p&gt;
&lt;h4&gt;MSE 复杂度&lt;/h4&gt;
&lt;p&gt;一眼 $O(n\times d)$&lt;/p&gt;
&lt;h4&gt;SA 复杂度&lt;/h4&gt;
&lt;h5&gt;退火总轮数&lt;/h5&gt;
&lt;p&gt;温度每次乘以 $\text{delta}=0.98$，直到 $T&amp;lt;\text{Tmin}$，次数为：&lt;/p&gt;
&lt;p&gt;$$k = \log_{0.98}\left(\frac{T_{\min}}{T_0}\right) = O\left(\log\left(\frac{1}{T_{\min}}\right)\right)$$&lt;/p&gt;
&lt;p&gt;代码中 $T_{\min} = 1e{-6}$，所以一般需要：&lt;/p&gt;
&lt;p&gt;$$\frac{\log(1e6)}{\log(1/0.98)} \approx \frac{13.8}{0.02} = 690 \text{ 次}$$&lt;/p&gt;
&lt;p&gt;所以我们记退火迭代次数为 $T_{\text{steps}} \approx 600 \sim 1000$&lt;/p&gt;
&lt;h5&gt;每次迭代&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;扰动 $d+1$ 个参数，$O(d)$&lt;/li&gt;
&lt;li&gt;调用一次 MSE，$O(n\times d)$&lt;/li&gt;
&lt;li&gt;复制俩数组 $O(d)$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总复杂度 $O(n\times d)$&lt;/p&gt;
&lt;p&gt;SA 总复杂度为 $O(T_{\text{steps}} \cdot n \cdot d)$。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;综上可知，总复杂度为 $O(T_{\text{steps}} \cdot n \cdot d\cdot k)$，其中 $k$ 为你跑 SA 的次数。&lt;/p&gt;
</content:encoded></item><item><title>关于一个黑暗中的萝卜般的 chatgpt bug 溯源</title><link>https://blog.mitufun.top/posts/%E5%85%B3%E4%BA%8E%E4%B8%80%E4%B8%AA%E9%BB%91%E6%9A%97%E4%B8%AD%E7%9A%84%E8%90%9D%E5%8D%9C%E8%88%AC%E7%9A%84-chatgpt-bug-%E6%BA%AF%E6%BA%90/%E5%85%B3%E4%BA%8E%E4%B8%80%E4%B8%AA%E9%BB%91%E6%9A%97%E4%B8%AD%E7%9A%84%E8%90%9D%E5%8D%9C%E8%88%AC%E7%9A%84-chatgpt-bug-%E6%BA%AF%E6%BA%90/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/%E5%85%B3%E4%BA%8E%E4%B8%80%E4%B8%AA%E9%BB%91%E6%9A%97%E4%B8%AD%E7%9A%84%E8%90%9D%E5%8D%9C%E8%88%AC%E7%9A%84-chatgpt-bug-%E6%BA%AF%E6%BA%90/%E5%85%B3%E4%BA%8E%E4%B8%80%E4%B8%AA%E9%BB%91%E6%9A%97%E4%B8%AD%E7%9A%84%E8%90%9D%E5%8D%9C%E8%88%AC%E7%9A%84-chatgpt-bug-%E6%BA%AF%E6%BA%90/</guid><description>一个黑暗中的萝卜</description><pubDate>Fri, 27 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;关于这个 bug 的起因&lt;/h3&gt;
&lt;p&gt;今天用 chatgpt voice mode 的时候，我麦克风并没有配置正确，在调整麦克风结束后发现 chatgpt 进行了如下的对话：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1735299988163.png&quot; alt=&quot;1735299988163&quot; /&gt;&lt;/p&gt;
&lt;p&gt;不明觉厉。当时我的麦克风选择的是一个虚拟麦克风，其功能是将电脑播放的声音通过一个软件重新发回给电脑。当时我电脑不仅没声，而且那个软件根本没有启动，所以不可能出现这段对话&lt;/p&gt;
&lt;h3&gt;溯源&lt;/h3&gt;
&lt;p&gt;进行简单的搜索，发现不少有趣的事情：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1735299970128.png&quot; alt=&quot;1735299970128&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.cnblogs.com/apachecn/p/18441513&quot;&gt;某个博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://learning.sohu.com/a/713003291_120101632&quot;&gt;某篇文章&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个 bug 并不少见啊&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;进一步搜索，发现了一个 github 仓库。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;SIXiaolong1117/WhisperPythonScript&quot;}&lt;/p&gt;
&lt;p&gt;其 v2mkv_s.py 代码中 49-54 行如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 遍历生成的文本结果，并将其添加到 SRT 对象中
for idx, segment in enumerate(result[&quot;segments&quot;]):
    if segment is not None:
        # 如果识别结果包含特定文本，则丢弃该行
        if &quot;请不吝点赞 订阅 转发 打赏支持明镜与点点栏目&quot; in segment[&quot;text&quot;]:
            continue
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;并且此仓库是为 openai 开源的一个名为 Whisper 的语音识别工具编写的脚本。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;openai/whisper&quot;}&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;进一步查询仓库中的 discussion：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1735300467910.png&quot; alt=&quot;1735300467910&quot; /&gt;&lt;/p&gt;
&lt;p&gt;答案呼之欲出&lt;/p&gt;
&lt;p&gt;根据 &lt;a href=&quot;https://github.com/openai/whisper/discussions/1783&quot;&gt;2023-11-9 发布的一个 discussion&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This problem exists in both v3 and v2 and has to do with Whisper hallucinating, especially when encountering periods of silence or no speech, and then it can also get stuck in a sort of loop like this. The difference is that the hallucinations probably just occur in different places in v2 and v3, but they still will happen in both cases. If you like whisper.cpp, you can make a feature request to limit this issue by preprocessing the file to cut out the silent or no speech parts first, then re-inserting those parts in the timestamps in postprocessing. There are other projects that already provide this feature, such as stable-ts and others (if you search the discussion board for hallucinations, you can find several more projects that work on improving the hallucination problem.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;楼主的推测：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The pattern of the ads seemed to be clear to me. Many subtitle editors like to embed ads in the front of the videos. These videos usually play silence or soft music at the beginning. The whisper models learned the silence or soft music are represented by those ads.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;似乎这被他们称作“幻觉”，而这种“幻觉”在越新版本的 whisper 中出现的更加频繁：https://github.com/ggerganov/whisper.cpp/issues/2191&lt;/p&gt;
&lt;p&gt;所以其实本质原因就是老版本的 whisper 训练模型用的数据可能比较少比较干净。后来 v2 v3 用到了一些视频网站的字幕数据，但是部分作者会在视频开头或结尾添加上一些标识（如“某某某字幕组制作”，“请不吝点赞 订阅 转发 打赏支持明镜与点点栏目”）等内容，而视频中所对应的声音数据常常是没有文字意义的混乱声音，导致了 whisper 在识别无声或混乱声音时出现如上的广告。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;关于解决方案&lt;/h3&gt;
&lt;p&gt;https://github.com/openai/whisper/discussions/1783#discussioncomment-7664639&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&apos;ve created PR &lt;a href=&quot;https://github.com/openai/whisper/pull/1838&quot;&gt;#1838&lt;/a&gt; which skips over any silence before a detected hallucination that is longer than &lt;code&gt;--hallucination_silence_threshold DURATION&lt;/code&gt; in seconds (I used 2 seconds). On the PR page I&apos;ve included some sample output of your example with a threshold of 2 seconds, and included some debug output to also print out whenever a hallucination was detected. The PR only skips over parts where Whisper didn&apos;t detect any speech, although Whisper can still fail to detect speech when there was some, and this PR doesn&apos;t address that.I can confirm this works more reliably with v2 than v3 on your example. For it to work with v3, it has to skip precisely the right amount of silence at the start for it to successfully pick up the start of the first utterance, but v3 has harder picking up the start of that speech. This might be because the speech starting at around 54 seconds is very soft/inaudible at the start. But v2 is more successful at picking up the first utterance.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;而且貌似这个改动已经被 &lt;a href=&quot;https://github.com/openai/whisper/discussions/1783#discussioncomment-7897494&quot;&gt;官方采纳了&lt;/a&gt;，但是 &lt;a href=&quot;https://github.com/ryanheise/whisper/tree/fix-hallucinations&quot;&gt;404&lt;/a&gt;。所以又被删了？&lt;/p&gt;
&lt;p&gt;所以现在的解决方案或许只有&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if &quot;请不吝点赞 订阅 转发 打赏支持明镜与点点栏目&quot; in segment[&quot;text&quot;]:
    continue
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>2024-9-22随笔</title><link>https://blog.mitufun.top/posts/2024-9-22%E9%9A%8F%E7%AC%94/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/2024-9-22%E9%9A%8F%E7%AC%94/</guid><description>随笔</description><pubDate>Sun, 22 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;感觉最近梦越来越真实了 确实有点分不清了&lt;/p&gt;
&lt;p&gt;甚至感觉梦里有些事情是真实发生的&lt;/p&gt;
</content:encoded></item><item><title>关于最近博客搭建出现的Bug</title><link>https://blog.mitufun.top/posts/%E5%85%B3%E4%BA%8E%E6%9C%80%E8%BF%91%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E5%87%BA%E7%8E%B0%E7%9A%84bug/%E5%85%B3%E4%BA%8E%E6%9C%80%E8%BF%91%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E5%87%BA%E7%8E%B0%E7%9A%84bug/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/%E5%85%B3%E4%BA%8E%E6%9C%80%E8%BF%91%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E5%87%BA%E7%8E%B0%E7%9A%84bug/%E5%85%B3%E4%BA%8E%E6%9C%80%E8%BF%91%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E5%87%BA%E7%8E%B0%E7%9A%84bug/</guid><description>未跟进 Cheerio 的更新而修改代码出现的错误</description><pubDate>Fri, 06 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2024.9.6 想改一下博客的 icon，结果一改：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1725726276621.png&quot; alt=&quot;1725726276621&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后查不出来错，其实现在也不知道为啥跳这个错。&lt;/p&gt;
&lt;p&gt;我就寻思也不能因为这个整个博客就寄掉了啊，就找 github 仓库里的历史版本，然后 clone 到本地。&lt;/p&gt;
&lt;p&gt;结果好家伙，原来的版本跑一边 &lt;code&gt;pnpm run build&lt;/code&gt; 结果也报错了：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The requested module &apos;cheerio&apos; does not provide an export named &apos;default&apos;
Stack trace:
at ModuleJob._instantiate (node:internal/modules/esm/module_job:134:21)
at async ModuleLoader.import (node:internal/modules/esm/loader:316:24)
at async ssrImport (file:///D:/Project/old-blog/node_modules/.pnpm/vite@5.4.3_@types+node@22.5.4_lightningcss@1.25.1_sass@1.78.0_stylus@0.63.0_terser@5.31.6/node_modules/vite/dist/node/chunks/dep-BaOMuo4I.js:52846:16)
at async instantiateModule (file:///D:/Project/old-blog/node_modules/.pnpm/vite@5.4.3_@types+node@22.5.4_lightningcss@1.25.1_sass@1.78.0_stylus@0.63.0_terser@5.31.6/node_modules/vite/dist/node/chunks/dep-BaOMuo4I.js:52904:5)
 ELIFECYCLE  Command failed with exit code 1.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;贼迷惑啊，上上个月搭博客还啥事没有，就蹦了个：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ERR_PNPM_OUTDATED_LOCKFILE  Cannot install with &quot;frozen-lockfile&quot; because pnpm-lock.yaml is not up 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后 &lt;a href=&quot;https://blog.csdn.net/thhhwr/article/details/136537959&quot;&gt;这篇博客&lt;/a&gt; 给出了解决方案，确实有效，删了 &lt;code&gt;pnpm-lock.yaml&lt;/code&gt; 然后就搭好了，后续传文件也啥事没有。过了俩月就报错是吧。&lt;/p&gt;
&lt;p&gt;直接给这段报错扔给 chatgpt，结果一堆车轱辘话，没啥卵用。&lt;/p&gt;
&lt;p&gt;然后就死马当活马医扔到百度帮我搜一下，好家伙翻到一个 &lt;a href=&quot;https://stackoverflow.com/questions/78856096/error-when-evaluating-ssr-module-f-oceanh-workspace-project-blog-astro-astro-co&quot;&gt;stackflow&lt;/a&gt;。好嘛，一模一样。而且：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Modified 27 days ago&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;寻思有救了，解答老哥扔了个 &lt;a href=&quot;https://github.com/natemoo-re/astro-icon/issues/231&quot;&gt;github 的 issue&lt;/a&gt;，一模一样，都是因为 cheerio。下面一堆改 package.json 的，但是我实测并没有用，override pnpm 也没用，直到看到二楼老哥：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It has something to do with the latest release of Cheerio
https://github.com/cheeriojs/cheerio/releases/tag/v1.0.0
It was tagged 6 hours ago. This seems more like an issue with &lt;code&gt;@iconify/tools&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;打开一看&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1725726896079.png&quot; alt=&quot;1725726896079&quot; /&gt;&lt;/p&gt;
&lt;p&gt;之后报错也给我提示了是在 &lt;code&gt;@iconify\tools\lib\svg\index.mjs&lt;/code&gt; 报的错，然后打开一看，好家伙第一行：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1725727401745.png&quot; alt=&quot;1725727401745&quot; /&gt;&lt;/p&gt;
&lt;p&gt;典中典，把老的引用方式改成 &lt;code&gt;import * as cheerio from &apos;cheerio&apos;;&lt;/code&gt;：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1725727475749.png&quot; alt=&quot;1725727475749&quot; /&gt;&lt;/p&gt;
&lt;p&gt;跑了遍 &lt;code&gt;pnpm run build&lt;/code&gt; 没啥问题，然后本地网站看了也没啥问题，我就把他 push 到了我仓库，然后让 vercel 给我搭一下。然后好嘛：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1725727600073.png&quot; alt=&quot;1725727600073&quot; /&gt;&lt;/p&gt;
&lt;p&gt;不多评价了。&lt;/p&gt;
&lt;p&gt;前几次主要报错是：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1725727654164.png&quot; alt=&quot;1725727654164&quot; /&gt;&lt;/p&gt;
&lt;p&gt;结果就是我本地改了，人家下的还是有 bug 的版本的。灵机一动，上传 &lt;code&gt;node_modules\@iconify\tools&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。然后就好了。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;具体这个 bug 产生原因就是，&lt;code&gt;cheerio&lt;/code&gt; 新版本引用方式要改，但是 &lt;code&gt;astro&lt;/code&gt; 使用的 &lt;code&gt;@iconify\tools&lt;/code&gt; 是老版本的还是采用老的应用方式导致无法正确引用 &lt;code&gt;cheerio&lt;/code&gt; 库。（这个问题在新版的 &lt;code&gt;@iconify\tools&lt;/code&gt; 已被解决，但是 &lt;code&gt;astro&lt;/code&gt; 并没有跟进。。。）&lt;/p&gt;
&lt;p&gt;而且 &lt;code&gt;cheerio&lt;/code&gt; 更新时间是上个月，恰好卡在我首次搭建博客和改 icon 中间，一直就没出现这个错。。。。&lt;/p&gt;
&lt;p&gt;找了两个晚上 bug 终于整好了。。。&lt;/p&gt;
</content:encoded></item><item><title>使用 Python 实现远程截图桌面并上传到服务端</title><link>https://blog.mitufun.top/posts/%E4%BD%BF%E7%94%A8-python-%E5%AE%9E%E7%8E%B0%E8%BF%9C%E7%A8%8B%E6%88%AA%E5%9B%BE%E6%A1%8C%E9%9D%A2%E5%B9%B6%E4%B8%8A%E4%BC%A0%E5%88%B0%E6%9C%8D%E5%8A%A1%E7%AB%AF/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/%E4%BD%BF%E7%94%A8-python-%E5%AE%9E%E7%8E%B0%E8%BF%9C%E7%A8%8B%E6%88%AA%E5%9B%BE%E6%A1%8C%E9%9D%A2%E5%B9%B6%E4%B8%8A%E4%BC%A0%E5%88%B0%E6%9C%8D%E5%8A%A1%E7%AB%AF/</guid><pubDate>Thu, 22 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;很早之前就想写了，前几天给实现了。&lt;/p&gt;
&lt;p&gt;整个程序分为两部分，客户端和服务端。&lt;/p&gt;
&lt;h3&gt;服务端&lt;/h3&gt;
&lt;p&gt;服务端很简单，只需要用 Flask 跑个服务器，然后监听几个 api 就行了。&lt;/p&gt;
&lt;p&gt;我具体实现的 api 就仨：upload、ban、unban，功能和他们名字一样。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import os
import time
from flask import Flask, request

app = Flask(__name__)

blacklist = []

@app.route(&apos;/upload&apos;, methods=[&apos;POST&apos;])
def upload_image():
    if &apos;screenshot&apos; not in request.files:
        return &apos;没有找到文件&apos;, 400

    file = request.files[&apos;screenshot&apos;]
    if file.filename == &apos;&apos;:
        return &apos;文件名称为空&apos;, 400
    client_name = request.headers.get(&apos;Client-Name&apos;)
    if client_name in blacklist:
        return &apos;Banned&apos;, 403

    save_path = os.path.join(os.getcwd(), &apos;screenshots&apos;, client_name)
    os.makedirs(save_path, exist_ok=True)

    timestamp = int(time.time())
    filename = f&apos;{client_name}_{timestamp}.png&apos;
    file.save(os.path.join(save_path, filename))

    return &apos;Uploaded&apos;, 200

@app.route(&apos;/ban/&amp;lt;username&amp;gt;&apos;, methods=[&apos;GET&apos;])
def add_to_blacklist(username):
    blacklist.append(username)
    return f&apos;Banned {username}&apos;, 200

@app.route(&apos;/unban/&amp;lt;username&amp;gt;&apos;, methods=[&apos;GET&apos;])
def remove_from_blacklist(username):
    if username in blacklist:
        blacklist.remove(username)
        return f&apos;Unbanned {username}&apos;, 200
    else:
        return f&apos;{username} is not banned&apos;, 404

if __name__ == &apos;__main__&apos;:
    app.run()

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;收到的图片会存在同目录下 /screenshot/用户名 文件夹下，并按时间戳保存。&lt;/p&gt;
&lt;p&gt;对于为什么要实现 ban 和 unban 这俩 api，纯纯就是因为如果一个人长期后台跑这个我电脑磁盘扛不住。&lt;/p&gt;
&lt;p&gt;这俩 api 用法也贼简单，浏览器访问 &lt;code&gt;/ban/&amp;lt;username&amp;gt;&lt;/code&gt; 或 &lt;code&gt;/unban/&amp;lt;username&amp;gt;&lt;/code&gt; 就能封禁和解封了。&lt;/p&gt;
&lt;h3&gt;客户端&lt;/h3&gt;
&lt;p&gt;客户端就比较麻烦了，主要是要有防杀功能。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import pyautogui
import pyscreenshot
import requests
import socket
import time
import os
import tempfile
import win32com.client
import winreg
import shutil
import ctypes

def take_screenshot_and_upload(upload_url):
  image = pyscreenshot.grab()
  fd, temp_file = tempfile.mkstemp(suffix=&quot;.png&quot;)
  os.close(fd)
  image.save(temp_file)
  client_name = socket.gethostname()
  headers = {
    &apos;Client-Name&apos;: client_name
  }
  try:
    with open(temp_file, &quot;rb&quot;) as f:
      response = requests.post(upload_url, files={&quot;screenshot&quot;: f}, headers=headers)
      for _ in range(5):
        try:
          os.remove(temp_file)
          break
        except PermissionError:
          print(f&quot;无法删除 {temp_file} 文件，正在重试...&quot;)
          time.sleep(0.5)
      return response
  except requests.exceptions.ConnectionError as e:
    print(f&quot;连接错误：{e}&quot;)
    return None

upload_url = &quot;http://[你的服务器地址]/upload&quot;

def set_auto_start():
  try:
    key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r&apos;Software\Microsoft\Windows\CurrentVersion\Run&apos;, 0, winreg.KEY_SET_VALUE)
    winreg.SetValueEx(key, &apos;WindowsMainProcess&apos;, 0, winreg.REG_SZ, os.path.abspath(__file__))
    winreg.CloseKey(key)
    print(f&quot;已设置为开机自启。&quot;)
  except Exception as e:
    print(f&quot;设置开机自启失败：{e}&quot;)

def check_admin_rights():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

def move_to_program_files():
  try:
    script_dir = os.path.dirname(os.path.abspath(__file__))
    target_path = r&apos;C:\Program Files\Windows&apos;
    os.makedirs(target_path, exist_ok=True)
    for filename in os.listdir(script_dir):
      source_file = os.path.join(script_dir, filename)
      shutil.move(source_file, target_path)
    print(f&quot;脚本和相关文件已移动到 {target_path}&quot;)
  except Exception as e:
    print(f&quot;移动脚本和相关文件失败：{e}&quot;)

def main():
  if (not check_admin_rights()) and os.path.abspath(__file__) != r&apos;C:\Program Files\Windows&apos;:
    print(&quot;需要管理员权限才能运行此程序！&quot;)
    os.system(&apos;pause&apos;)
    return
  if os.path.abspath(__file__) != r&apos;C:\Program Files\Windows&apos;:
    move_to_program_files()
    set_auto_start()
  while True:
    response = take_screenshot_and_upload(upload_url)
    if response:
      print(f&quot;上传状态码：{response.status_code}&quot;)
      print(f&quot;上传响应：{response.text}&quot;)
    else:
      print(&quot;连接失败，将在 10 秒后重试...&quot;)
    time.sleep(10)

if __name__ == &quot;__main__&quot;:
  main()

&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;code&gt;take_screenshot_and_upload()&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;使用 &lt;code&gt;pyscreenshot&lt;/code&gt; 截图当前桌面，然后将图片临时保存到本地。&lt;/p&gt;
&lt;p&gt;用 &lt;code&gt;requests&lt;/code&gt; 上传截图，在此期间，如果网络连接速度较慢，会出现临时截图文件被占用无法删除导致程序异常退出。我的方法就是循环删除，直到能删掉（没想到更好的方法 嘻嘻&lt;/p&gt;
&lt;p&gt;同时如果服务端没开的话也得抓一下这个异常，不然又退出了。&lt;/p&gt;
&lt;h4&gt;&lt;code&gt;set_auto_start()&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;开机自启，需要管理员权限，故在 main 开头就得检测是否有管理员权限。但当此程序已被移动到 &lt;code&gt;C:\Program Files\Windows\&lt;/code&gt; 目录下，则意味着已经设置成功，在 main 开头不需要检测权限，否则每次开机自启后都无法成功运行。&lt;/p&gt;
&lt;h3&gt;关于如何远程连接服务端&lt;/h3&gt;
&lt;p&gt;我采取的方案是内网穿透。用 OpenFrp 穿透一下内网服务器（默认为 127.0.0.1:5000），隧道类型选 TCP，然后会给你一串网址，例如 &lt;code&gt;example.com:1234&lt;/code&gt;。然后你把客户端中 &lt;code&gt;[你的服务器地址]&lt;/code&gt; 改为 &lt;code&gt;example.com:1234&lt;/code&gt; 即可。&lt;/p&gt;
&lt;p&gt;当然，如果你有域名，CNAME 类型记录一下 &lt;code&gt;example.com&lt;/code&gt;，然后服务器地址后头记得加上端口 &lt;code&gt;1234&lt;/code&gt; 就好了。挺简单的也。&lt;/p&gt;
</content:encoded></item><item><title>以一种简单的方式维持内网穿透的稳定性</title><link>https://blog.mitufun.top/posts/%E4%BB%A5%E4%B8%80%E7%A7%8D%E7%AE%80%E5%8D%95%E7%9A%84%E6%96%B9%E5%BC%8F%E7%BB%B4%E6%8C%81%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E7%9A%84%E7%A8%B3%E5%AE%9A%E6%80%A7/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/%E4%BB%A5%E4%B8%80%E7%A7%8D%E7%AE%80%E5%8D%95%E7%9A%84%E6%96%B9%E5%BC%8F%E7%BB%B4%E6%8C%81%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E7%9A%84%E7%A8%B3%E5%AE%9A%E6%80%A7/</guid><description>以一种简单的方式维持内网穿透的稳定性</description><pubDate>Tue, 06 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在使用 openfrp 时时常出现因更新导致无法连接的问题，虽然只需要我们手动重启一下就行，但是还是挺麻烦的，还得别人提醒。&lt;/p&gt;
&lt;p&gt;但是 openfrp 提供的地址是附有端口的，我们需要检查某一端口是否能连接正常。普通的 ping 无法实现，我们可以使用 tcping。&lt;a href=&quot;https://elifulkerson.com/projects/tcping.php&quot;&gt;下载地址&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;将下载的 tcping.exe 或者 tcping64.exe 放置到 C:\Windows\System32 目录下（即与 ping.exe 同目录）&lt;/p&gt;
&lt;p&gt;如果你下载的是 tcping.exe，命令则使用 tcping 开头。如果是 tcping64.exe，命令则以 tcping64 开头。&lt;/p&gt;
&lt;p&gt;:::tip&lt;/p&gt;
&lt;p&gt;当然，如果你愿意，你可以将你的 tcping64.exe 改名为 tcping.exe。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;p&gt;官方 -help：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;NAME
    tcping - simulate &quot;ping&quot; over tcp by establishing a connection to network hosts.
    Measures the time for your system to [SYN], receive the target&apos;s [SYN][ACK] and send [ACK].  Note that the travel time for
    the last ACK is not included - only the time it takes to be put on the wire a the sending end.
SYNOPSIS
    tcping [-tdsvf46] [-i interval] [-n times] [-w interval] [-b n] [-r times][-j depth] [--tee filename] [-f] destination [port]
DESCRIPTION
    tcping measures the time it takes to perform a TCP 3-way handshake (SYN, SYN/ACK, ACK) between itself and a remote host.
    The travel time of the outgoing final ACK is not included, only the (minimal) amount of time it has taken to drop it on
    the wire at the near end.  This allows the travel time of the (SYN, SYN/ACK) to approximate the travel time of the
    ICMP (request, response) equivalent.
OPTIONS
    -4      Prefer using IPv4
    -6      Prefer using IPv6
    -t      ping continuously until stopped via control-c
    -n count
            send _count_ pings and then stop.  Default 4.
    -i interval
            Wait _interval_ seconds between pings.  Default 1.  Decimals permitted.
    -w interval
            Wait _interval_ seconds for a response.  Default 2.  Decimals permitted.
    -d      include date and time on every output line
    -f      Force sending at least one byte in addition to making the connection.
    -g count
            Give up after _count_ failed pings.
    -b type
            Enable audible beeps.
            &apos;-b 1&apos; will beep &quot;on down&quot;.  If a host was up, but now its not, beep.
            &apos;-b 2&apos; will beep &quot;on up&quot;.  If a host was down, but now its up, beep.
            &apos;-b 3&apos; will beep &quot;on change&quot;.  If a host was one way, but now its the other, beep.
            &apos;-b 4&apos; will beep &quot;always&quot;.
    -c      only show output on a changed state
    -r count
            Every _count_ pings, we will perform a new DNS lookup for the host in case it changed.
    -s      Exit immediately upon a success. 
    -v      Print version and exit.
    -S source_address
            Use _source_address_ as the tcp client&apos;s source address.  Must be a valid IP address on the client system.

    -j      Calculate jitter.  Jitter is defined as the difference between the last response time and the historical average.
    -js depth
            Calculate jitter, as with -j but with an optional _depth_ argument specified. If _depth_ is specified tcping will
            use the prior _depth_ values to calculate a rolling average.
    --tee _filename_
            Duplicate output to the _filename_ specified.  Windows can still not be depended upon to have a useful command line 
            environment. Don&apos;t tease me, *nix guys.   
    --file
            Treat the &quot;destination&quot; option as a filename.  That file becomes a source of destinations, looped through on a
            line by line basis.  Some options don&apos;t work in this mode and statistics will not be kept.
    destination
            A DNS name, an IP address, or (in &quot;http&quot; mode) a URL.
            Do not specify the protocol (&quot;http://&quot;) in &quot;http&quot; mode.  Also do not specify server port via &quot;:port&quot; syntax.
            For instance:   &quot;tcping http://www.elifulkerson.com:8080/index.html&quot; would fail
            Use the style:  &quot;tcping www.elifulkerson.com/index.html 8080&quot; instead.                       
    port
            A numeric TCP port, 1-65535.  If not specified, defaults to 80.
    --header
            include a header with the command line arguments and timestamp.  Header is implied if using --tee.
    --block
            use a &quot;blocking&quot; socket to connect.  This prevents -w from working, uses the default timeout of around 20 seconds,
            and might break other expected behavior.  However, it can detect an actively refused connection vs a timeout.   
HTTP MODE OPTIONS   
    -h      Use &quot;http&quot; mode.  In http mode we will attempt to GET the specified document and return additional values including
            the document&apos;s size, http response code, kbit/s.
    -u      In &quot;http&quot; mode, include the target URL on each output line.
    --post Use POST instead of GET in http mode.
    --head Use HEAD instead of GET in http mode.
    --get Shorthand to invoke &quot;http&quot; mode for consistency&apos;s sake.
    --proxy-server _proxyserver_
            Connect to _proxyserver_ to request the url rather than the server indicated in the url itself.
    --proxy-port _port_
            Specify the numeric TCP port of the proxy server.  Defaults to 3128.
    --proxy-credentials username:password
            Specify a username:password pair which is sent as a &apos;Proxy-Authorization: Basic&apos; header.
RETURN VALUE
    tcping returns 0 if all pings are successful, 1 if zero pings are successful and 2 for mixed outcome.
BUGS/REQUESTS
    Please report bugs and feature requests to the author via contact information on http://www.elifulkerson.com
AVAILABILITY
    tcping is available at http://www.elifulkerson.com/projects/tcping.php
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note&lt;/p&gt;
&lt;p&gt;这个命令使用 &lt;code&gt;system()&lt;/code&gt; 运行后会返回结果，&lt;code&gt;1&lt;/code&gt; 为无法连接，&lt;code&gt;0&lt;/code&gt; 为连接成功。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;p&gt;因此我们可以写出一段周期检测对应远程端口是否可访问的代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include&amp;lt;iostream&amp;gt;
#include&amp;lt;climits&amp;gt;
#include&amp;lt;cstring&amp;gt;
#include&amp;lt;cstdio&amp;gt;
#include&amp;lt;Windows.h&amp;gt;
#include&amp;lt;chrono&amp;gt;
using namespace std;

int main() {
    while (1) {
	    time_t now = time(nullptr);
	    string s = ctime(&amp;amp;now);
		cout &amp;lt;&amp;lt; &quot;&amp;gt;&amp;gt;&amp;gt; [&quot; &amp;lt;&amp;lt; s.substr(0, s.size() - 1) &amp;lt;&amp;lt; &apos;]&apos;;
        if (system(&quot;tcping -n 1 [你的远程地址] [端口]&quot;)) {
        	cout &amp;lt;&amp;lt; &quot;&amp;gt;&amp;gt;&amp;gt; START FINAL CHECK.&quot; &amp;lt;&amp;lt; endl;
        	bool flag = false;
        	for (int i = 1;i &amp;lt;= 3;i++) {
        		cout &amp;lt;&amp;lt; &quot;&amp;gt;&amp;gt;&amp;gt; CHECK NO. &quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot;&quot;;
        		if (!system(&quot;tcping -n 1 [你的远程地址] [端口]&quot;)) {
        			flag = true;
        			break;
				}
				Sleep(2000);
			}
			if (!flag) {
				system(&quot;start rfrp.bat&quot;);
			}
			cout &amp;lt;&amp;lt; &quot;&amp;gt;&amp;gt;&amp;gt; FINAL CHECK DONE.&quot; &amp;lt;&amp;lt; endl;
        }
        Sleep(60000);
    } 
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::important&lt;/p&gt;
&lt;p&gt;其中 &lt;code&gt;if(!flag)&lt;/code&gt; 后会运行重启等相关操作，自行修改。&lt;/p&gt;
&lt;p&gt;记得改自己的内网穿透地址。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
</content:encoded></item><item><title>使用 Thanos 给大型 MC 存档瘦身</title><link>https://blog.mitufun.top/posts/%E4%BD%BF%E7%94%A8-thanos-%E7%BB%99%E5%A4%A7%E5%9E%8B-mc-%E5%AD%98%E6%A1%A3%E7%98%A6%E8%BA%AB/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/%E4%BD%BF%E7%94%A8-thanos-%E7%BB%99%E5%A4%A7%E5%9E%8B-mc-%E5%AD%98%E6%A1%A3%E7%98%A6%E8%BA%AB/</guid><description>使用 Thanos 给大型 MC 存档瘦身</description><pubDate>Tue, 06 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;::github{repo=&quot;aternosorg/thanos&quot;}&lt;/p&gt;
&lt;p&gt;（以下为官方 README 中文翻译）&lt;/p&gt;
&lt;p&gt;Thanos是一个PHP库，可以自动检测并删除Minecraft世界中未使用的区块。这可以将世界的文件大小减少50%以上。&lt;/p&gt;
&lt;p&gt;除现有工具外，此库不使用 blocklist（我确实不知道这个该如何翻译）。相反，使用占用时间值来确定是否使用块。这可以防止使用过的块有时会被意外删除，并使此库与大多数mods和插件兼容。&lt;/p&gt;
&lt;p&gt;目前，仅支持Minecraft Anvil世界格式（Minecraft Java版）。&lt;/p&gt;
&lt;h2&gt;安装&lt;/h2&gt;
&lt;p&gt;:::important[一些必须的环境]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP 7.4&lt;/li&gt;
&lt;li&gt;脑子&lt;/li&gt;
&lt;li&gt;手&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;顺带一提，这个 php 我是用宝塔面板装的（&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h3&gt;开始&lt;/h3&gt;
&lt;p&gt;创建一个新的空文件夹，并执行以下命令安装（没 php 跑不了）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;composer require aternos/thanos
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可能会提示一些函数 &lt;code&gt;has been disabled for security reasons&lt;/code&gt;，你去宝塔面板找到 php-7.4 管理，禁用函数，给报错的函数都开开就行了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./%E5%88%A0%E9%99%A4%E7%A6%81%E7%94%A8%E5%87%BD%E6%95%B0.png&quot; alt=&quot;删除禁用函数&quot; /&gt;&lt;/p&gt;
&lt;p&gt;删除完了别忘了再跑一遍 &lt;code&gt;composer require aternos/thanos&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;使用&lt;/h3&gt;
&lt;p&gt;:::caution&lt;/p&gt;
&lt;p&gt;以下命令必须在项目根目录下运行。&lt;/p&gt;
&lt;p&gt;运行前关闭游戏。&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./vendor/aternos/thanos/thanos.php 世界文件夹名称 输出文件夹名称
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;等待一段时间，可能要很久，当出现 &lt;code&gt;Removed xxx chunks in xxx seconds&lt;/code&gt; 时即说明优化完成。此时输出文件夹内就是优化完的存档。&lt;/p&gt;
&lt;p&gt;但是，如果你的存档过大，这个命令要运行很久，这个命令无法提供当前的优化进度，如果死机了你也不知道。那你可以使用我写的脚本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/php
&amp;lt;?php

use Aternos\Thanos\Helper;
use Aternos\Thanos\Thanos;
use Aternos\Thanos\World\AnvilWorld;

require_once &apos;vendor/autoload.php&apos;;

$startTime = microtime(true);
$world = new AnvilWorld(&quot;D:/MinecraftServer/backup/world&quot;, &quot;D:/MinecraftServer/world&quot;);
$cnt = 0;

echo &quot;Copying other files...\n&quot;;
$world-&amp;gt;copyOtherFiles(); //copy non-region files

foreach ($world as $chunk){
  if($chunk-&amp;gt;getInhabitedTime() &amp;gt; 0){
    $chunk-&amp;gt;save();
  }
  else {
    $cnt++;
    echo &quot;Removed $cnt chunks\n&quot;;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;具体使用方法：打开此目录 &lt;code&gt;\vendor\aternos\thanos&lt;/code&gt;，打开 &lt;code&gt;thanos.php&lt;/code&gt;，将里面的代码替换为我提供的代码。最后退回到根目录运行 &lt;code&gt;./vendor/aternos/thanos/thanos.php 世界文件夹名称 输出文件夹名称&lt;/code&gt; 命令即可。&lt;/p&gt;
</content:encoded></item><item><title>滑动窗口 O(n) 的分块做法</title><link>https://blog.mitufun.top/posts/%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3-on-%E7%9A%84%E5%88%86%E5%9D%97%E5%81%9A%E6%B3%95/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3-on-%E7%9A%84%E5%88%86%E5%9D%97%E5%81%9A%E6%B3%95/</guid><description>搬运自我的 cnblogs</description><pubDate>Sat, 28 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::info&lt;/p&gt;
&lt;p&gt;此为本人于 2022-05-28 初次发表在 cnblogs 的内容，迁移至此。&lt;a href=&quot;https://www.cnblogs.com/luogu-int64/p/16320845.html&quot;&gt;阅读原文&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;p&gt;一种复杂度为 $\mathcal{O}(n)$ 的分块做法。不需要开 O2。&lt;/p&gt;
&lt;p&gt;显然，这题可以想出一种 $\mathcal{O}(n\sqrt{n})$ 的垃圾分块做法，过不了，实测只有 &lt;a href=&quot;https://www.luogu.com.cn/record/76536917&quot;&gt;70 分&lt;/a&gt;，但是开 O2 可过，但是这样就没有优化的乐趣了。&lt;/p&gt;
&lt;p&gt;观察查询阶段：&lt;/p&gt;
&lt;p&gt;同一个块内我们不考虑，因为这部分直接暴力即可。看两端点不在同一个块内的情况，朴素代码如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for (int i = l; i &amp;lt;= b[bel[l]].ed; i++) {
	minv = min(minv, a[i]);
	maxv = max(maxv, a[i]);
}
for (int i = b[bel[r]].st; i &amp;lt;= r; i++) {
	minv = min(minv, a[i]);
	maxv = max(maxv, a[i]);
}
for (int i = bel[l] + 1; i &amp;lt; bel[r]; i++) {
	minv = min(minv, b[i].minv);
	maxv = max(maxv, b[i].maxv);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们使用了比较大的时间在暴力计算零散块的值，这会花费很多时间。（之所以这样说，是因为如果注释了前两个暴力的 for 之后，我们发现&lt;a href=&quot;https://www.luogu.com.cn/record/76537264&quot;&gt;只有一个点超时了&lt;/a&gt;）&lt;/p&gt;
&lt;p&gt;注意到，这里零散块的暴力都是从一个块的起点或终点到某个点之前的最值，我们可以使用前缀和后缀最值来实现 $\mathcal{O}(1)$ 查询块的起点、终点到一个点之间的最值。我的代码中使用 premin/max 和 sufmin/max 分别表示前缀最小最大值和后缀最小最大值。&lt;/p&gt;
&lt;p&gt;那么恭喜，使用这种方法我们可以得到 &lt;a href=&quot;https://www.luogu.com.cn/record/76490775&quot;&gt;90 pts&lt;/a&gt;，正好对应了之前注释掉的评测记录。说明这种优化是大有作用的。&lt;/p&gt;
&lt;p&gt;此刻，你发现你陷入了一个窘境——你想不出别的方法优化了。这里，我们就需要对块长入手。&lt;/p&gt;
&lt;p&gt;我们要充分发挥 &lt;s&gt;人类的智慧&lt;/s&gt; 前缀最值和后缀最值的作用，因为使用这两个数组可以 $\mathcal{O}(1)$ 找到最值。&lt;/p&gt;
&lt;p&gt;能用到前缀最值和后缀最值的情况只有当查询的两个端点在不同的块内。为了达到这个目标，我们需要将块长设置为 $k-1$。（我的代码中 $k$ 与块的个数重复了，于是使用 $l$ 代替）可能说的不是很清楚，我画个图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.luogu.com.cn/upload/image_hosting/kpduogal.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上图中红色框表示块，绿色框表示查询区间。对于查询区间的 ①，可以看做是从 $l$ 到 $l$ 所在的块末尾的最值（使用后缀最值数组），② 同理可以看做是从 $r$ 所在的块的起始到 $r$ 的最值（使用前缀最值数组）。这样可以直接 $\mathcal{O}(1)$ 解决查询问题。&lt;/p&gt;
&lt;p&gt;那么时间复杂度也就降到了 $\mathcal{O}(n)$，好像不能再低了。&lt;/p&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#include&amp;lt;iostream&amp;gt;
#include&amp;lt;cmath&amp;gt;
#include&amp;lt;ctype.h&amp;gt;
#include&amp;lt;climits&amp;gt;
#include&amp;lt;vector&amp;gt;
using namespace std;

#define int long long

const int maxn = 1e6 + 10;
const int maxblocksize = 1010;

int n, l;
int a[maxn];

struct block {
    int st, ed;
    vector&amp;lt;int&amp;gt; premax, premin;
    vector&amp;lt;int&amp;gt; sufmax, sufmin;
};
vector&amp;lt;block&amp;gt; b;

int blocksize, k, bel[maxn];

void init() {
    blocksize = l - 1, k = n / blocksize;
    b.resize(k + 5);
    for (int i = 1; i &amp;lt;= k; i++) {
        b[i].st = b[i - 1].ed + 1;
        b[i].ed = b[i].st + blocksize - 1;
    }
    if (b[k].ed != n) {
        k++;
        b[k].st = b[k - 1].ed + 1;
        b[k].ed = n;
    }
    for (int i = 1; i &amp;lt;= k; i++) {
        b[i].premax.resize(b[i].ed - b[i].st + 20);
        b[i].premin.resize(b[i].ed - b[i].st + 20);
        b[i].sufmax.resize(b[i].ed - b[i].st + 20);
        b[i].sufmin.resize(b[i].ed - b[i].st + 20);
        b[i].premax[0] = b[i].sufmax[b[i].ed + 1 - b[i].st + 1] = LLONG_MIN;
        b[i].premin[0] = b[i].sufmin[b[i].ed + 1 - b[i].st + 1] = LLONG_MAX;
        for (int j = b[i].st; j &amp;lt;= b[i].ed; j++) {
            bel[j] = i;
            b[i].premax[j - b[i].st + 1] = max(b[i].premax[j - b[i].st], a[j]);
            b[i].premin[j - b[i].st + 1] = min(b[i].premin[j - b[i].st], a[j]);
        }
        for (int j = b[i].ed; j &amp;gt;= b[i].st; j--) {
            b[i].sufmax[j - b[i].st + 1] = max(b[i].sufmax[j - b[i].st + 2], a[j]);
            b[i].sufmin[j - b[i].st + 1] = min(b[i].sufmin[j - b[i].st + 2], a[j]);
        }
    }
    return;
}
pair&amp;lt;int, int&amp;gt; query(int l, int r) {
    int minv = LLONG_MAX, maxv = LLONG_MIN;
    minv = min(minv, b[bel[l]].sufmin[l - b[bel[l]].st + 1]);
    minv = min(minv, b[bel[r]].premin[r - b[bel[r]].st + 1]);
    maxv = max(maxv, b[bel[l]].sufmax[l - b[bel[l]].st + 1]);
    maxv = max(maxv, b[bel[r]].premax[r - b[bel[r]].st + 1]);
    return make_pair(minv, maxv);
}

pair&amp;lt;int, int&amp;gt; ans[maxn];

signed main() {
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; l;
    for (int i = 1; i &amp;lt;= n; i++) {
        cin &amp;gt;&amp;gt; a[i];
    }
    if (l == 1) {
        for (int i = 1; i &amp;lt;= n; i++) {
            cout &amp;lt;&amp;lt; a[i] &amp;lt;&amp;lt; &apos; &apos;;
        }
        cout &amp;lt;&amp;lt; endl;
        for (int i = 1; i &amp;lt;= n; i++) {
            cout &amp;lt;&amp;lt; a[i] &amp;lt;&amp;lt; &apos; &apos;;
        }
        cout &amp;lt;&amp;lt; endl;
        return 0;
    }
    init();
    int cnt = 0;
    for (int i = 1; i + l - 1 &amp;lt;= n; i++) {
        ans[++cnt] = query(i, i + l - 1);
    }
    for (int i = 1; i &amp;lt;= cnt; i++) {
        cout &amp;lt;&amp;lt; ans[i].first &amp;lt;&amp;lt; &apos; &apos;;
    }
    cout &amp;lt;&amp;lt; endl;
    for (int i = 1; i &amp;lt;= cnt; i++) {
        cout &amp;lt;&amp;lt; ans[i].second &amp;lt;&amp;lt; &apos; &apos;;
    }
    cout &amp;lt;&amp;lt; endl;
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>珂朵莉树学习笔记</title><link>https://blog.mitufun.top/posts/%E7%8F%82%E6%9C%B5%E8%8E%89%E6%A0%91%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/%E7%8F%82%E6%9C%B5%E8%8E%89%E6%A0%91%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</guid><description>珂朵莉树学习笔记</description><pubDate>Thu, 28 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;我们以 CF896C 为模板来介绍珂朵莉树&lt;/p&gt;
&lt;h3&gt;珂朵莉树的实现&lt;/h3&gt;
&lt;p&gt;看题可得，有一个操作会导致一片区间内值相等。因此我们自然能想到，如果把这一段区间看成一个点，那么自然就可以节省很多力。&lt;/p&gt;
&lt;h4&gt;储存珂朵莉树&lt;/h4&gt;
&lt;p&gt;我们用一个结构体来作为珂朵莉树的结点：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;struct node {
    int l, r;
    mutable int v;
    bool operator&amp;lt; (const node&amp;amp; rhs) const {
        return this-&amp;gt;l &amp;lt; rhs.l;
    }
    node(int ll, int rr, int vv) {
        l = ll, r = rr, v = vv;
    }
    node(int ll) {
        l = ll;
    }
};
set&amp;lt;node&amp;gt; s;
#define IT set&amp;lt;node&amp;gt;::iterator
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个结构体中 $l$ 和 $r$ 分别对应该结点所对应的左区间和右区间，$v$ 是当前区间的值。注意，$v$ 需要被 $\text{mutable}$ 关键字修饰，这样才能在 $s$ 中用迭代器修改。随后重载小于号，并写出两个构造函数。我们用一个储存 $\text{node}$ 的 $\text{set}$ 来储存珂朵莉树。&lt;/p&gt;
&lt;h4&gt;分裂函数&lt;/h4&gt;
&lt;p&gt;但是，我们很容易发现：在进行查询的时候，我们不能保证查询的区间端点一定在结构体结点中，因此需要一个可以查找区间左右端点，获取到需要进行操作的区间，这便引出了下面的分裂函数：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IT split(int pos) {
    IT it = s.lower_bound(node(pos));
    if (it != s.end() &amp;amp;&amp;amp; it-&amp;gt;l == pos) {
        return it;
    }
    it--;
    int l = it-&amp;gt;l, r = it-&amp;gt;r, v = it-&amp;gt;v;
    s.erase(it);
    s.insert(node(l, pos - 1, v));
    return s.insert(node(pos, r, v)).first;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;推平函数&lt;/h4&gt;
&lt;p&gt;如果没有推平操作的话，珂朵莉树就会退化为暴力。因此，推平操作是珂朵莉树不可或缺的一部分。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void assign(int l, int r, int v) {
    IT itr = split(r + 1), itl = split(l);
    s.erase(itl, itr);
    s.insert(node(l, r, v));
    return;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段代码很好理解，首先获得左端点和右端点迭代器，**注意，一定要先获取右端点再获取左端点，否则会出错。**然后用 $\text{set}$ 的 $\text{erase}$ 函数删除从左端点到右端点内的所有结点，最后再插入进去一个对应区间的结点。由于数据是随机的，所以 $\text{assign}$ 操作会占到 $25%$ 的情况以上。我们可以写一个随机生成数据的代码，可以发现，珂朵莉树的结点数大约到达了 $\log$ 级别，而且速度很快。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;珂朵莉树的高效是由随机的 $\text{assign}$ 操作保证的。&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;添加函数&lt;/h4&gt;
&lt;p&gt;十分简单，直接暴力即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void add(int l, int r, int v) {
    IT itr = split(r + 1), itl = split(l);
    for (IT it = itl; it != itr; it++) {
        it-&amp;gt;v += v;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意，如果你结构体中 $v$ 并不是一个被 $\text{mutable}$ 关键字修饰的变量，那这里就会报错。&lt;/p&gt;
&lt;h4&gt;区间第 $k$ 小&lt;/h4&gt;
&lt;p&gt;同样，先提取区间，用一个 $\text{vector}$ 存区间内所有值，然后暴力查值即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int kth(int l, int r, int k) {
    IT itr = split(r + 1), itl = split(l);
    vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; v; //first 存对应的值，second 存区间元素个数
    v.clear();
    for (IT it = itl;it != itr;it++) {
        v.push_back(make_pair(it-&amp;gt;v, it-&amp;gt;r - it-&amp;gt;l + 1));
    }
    sort(v.begin(), v.end());
    for (int i = 0;i &amp;lt; v.size();i++) {
        k -= v[i].second;
        if (k &amp;lt;= 0) {
            return v[i].first;
        }
    }
    return -1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;区间幂次和&lt;/h4&gt;
&lt;p&gt;很简单，写个快速幂暴力即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int qpow(int a, int b, int m) {
    int ans = 1;
    a %= m;
    while (b) {
        if (b &amp;amp; 1) {
            ans = (ans * a) % m;
        }
        a = (a * a) % m;
        b &amp;gt;&amp;gt;= 1;
    }
    return ans;
}
int query(int l, int r, int x, int y) {
    IT itr = split(r + 1), itl = split(l);
    int res = 0;
    for (IT it = itl;it != itr;it++) {
        res = (res + (it-&amp;gt;r - it-&amp;gt;l + 1) * qpow(it-&amp;gt;v, x, y)) % y;
    }
    return res;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;总体代码&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;set&amp;gt;
#include &amp;lt;vector&amp;gt;
using namespace std;

#define int long long

struct node {
    int l, r;
    mutable int v;
    node(int ll, int rr, int vv) { l = ll, r = rr, v = vv; }
    node(int ll) { l = ll; }
    bool operator&amp;lt;(const node&amp;amp; rhs) const { return l &amp;lt; rhs.l; }
};
#define IT set&amp;lt;node&amp;gt;::iterator
set&amp;lt;node&amp;gt; s;

IT split(int pos) {
    IT it = s.lower_bound(node(pos));
    if (it != s.end() &amp;amp;&amp;amp; it-&amp;gt;l == pos) {
        return it;
    }
    it--;
    int l = it-&amp;gt;l, r = it-&amp;gt;r, v = it-&amp;gt;v;
    s.erase(it);
    s.insert(node(l, pos - 1, v));
    return s.insert(node(pos, r, v)).first;
}
void assign(int l, int r, int v) {
    IT itr = split(r + 1), itl = split(l);
    s.erase(itl, itr);
    s.insert(node(l, r, v));
}
void add(int l, int r, int v) {
    IT itr = split(r + 1), itl = split(l);
    for (IT it = itl; it != itr; it++) {
        it-&amp;gt;v += v;
    }
}
int kth(int l, int r, int k) {
    IT itr = split(r + 1), itl = split(l);
    vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; vec;
    vec.clear();
    for (IT it = itl; it != itr; it++) {
        vec.push_back(make_pair(it-&amp;gt;v, it-&amp;gt;r - it-&amp;gt;l + 1));
    }
    sort(vec.begin(), vec.end());
    for (int i = 0; i &amp;lt; vec.size(); i++) {
        k -= vec[i].second;
        if (k &amp;lt;= 0) {
            return vec[i].first;
        }
    }
    return -1;
}
int qpow(int a, int b, int y) {
    int res = 1;
    a %= y;
    while (b) {
        if (b &amp;amp; 1) {
            res = (res * a) % y;
        }
        a = (a * a) % y;
        b &amp;gt;&amp;gt;= 1;
    }
    return res;
}
int query(int l, int r, int x, int y) {
    IT itr = split(r + 1), itl = split(l);
    int res = 0;
    for (IT it = itl; it != itr; it++) {
        res = (res + (it-&amp;gt;r - it-&amp;gt;l + 1) * qpow(it-&amp;gt;v, x, y)) % y;
    }
    return res;
}

int seed, n, m, vmax;
int rnd() {
    int ret = (signed)seed;
    seed = (seed * 7 + 13) % 1000000007;
    return ret;
}
signed main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m &amp;gt;&amp;gt; seed &amp;gt;&amp;gt; vmax;
    for (int i = 1; i &amp;lt;= n; i++) {
        int v = (rnd() % vmax) + 1;
        s.insert(node(i, i, v));
    }
    for (int i = 1; i &amp;lt;= m; i++) {
        int opt = (rnd() % 4) + 1;
        int l = (rnd() % n) + 1;
        int r = (rnd() % n) + 1;
        int x, y;
        if (l &amp;gt; r) {
            swap(l, r);
        }
        if (opt == 3) {
            x = (rnd() % (r - l + 1)) + 1;
        } else {
            x = (rnd() % vmax) + 1;
        }
        if (opt == 4) {
            y = (rnd() % vmax) + 1;
        }

        // Comment
        if (opt == 1) {
            add(l, r, x);
        }
        if (opt == 2) {
            assign(l, r, x);
        }
        if (opt == 3) {
            cout &amp;lt;&amp;lt; kth(l, r, x) &amp;lt;&amp;lt; endl;
        }
        if (opt == 4) {
            cout &amp;lt;&amp;lt; query(l, r, x, y) &amp;lt;&amp;lt; endl;
        }
    }
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>社区帮助</title><link>https://blog.mitufun.top/posts/%E7%A4%BE%E5%8C%BA%E5%B8%AE%E5%8A%A9/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/%E7%A4%BE%E5%8C%BA%E5%B8%AE%E5%8A%A9/</guid><description>社区帮助</description><pubDate>Sat, 04 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;社区帮助&lt;/h2&gt;
&lt;h3&gt;发帖&lt;/h3&gt;
&lt;p&gt;PC 端点击左侧“发布主题”，填写你要发的内容后选择标签即可。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1740805313221.png&quot; alt=&quot;1740805313221&quot; /&gt;&lt;/p&gt;
&lt;p&gt;手机端点击右上角的笔，填写你要发的内容后选择标签即可。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1740805283635.png&quot; alt=&quot;1740805283635&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;匿名发帖&lt;/h3&gt;
&lt;p&gt;发帖前点击匿名发布即可，如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1740813061264.png&quot; alt=&quot;1740813061264&quot; /&gt;&lt;/p&gt;
&lt;p&gt;开了匿名也要注意点言辞奥&lt;/p&gt;
&lt;h3&gt;删帖&lt;/h3&gt;
&lt;p&gt;如下图所示进行操作：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1741003671732.png&quot; alt=&quot;1741003671732&quot; /&gt;&lt;/p&gt;
&lt;p&gt;回到主页你会发现你的帖子旁边头像上有个小垃圾桶，代表已经删除成功（如下图所示）。之所以还在展示，是因为社区具有回收站机制，你可以在一段时间内反悔并恢复帖子。无须担心，没人会再看见你的帖子的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1741003952363.png&quot; alt=&quot;1741003952363&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;善用举报功能&lt;/h3&gt;
&lt;p&gt;如果有让你感到不适，或者违反社区规则的内容出现，你可以进行举报。具体方法如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1740804812384.png&quot; alt=&quot;1740804812384&quot; /&gt;&lt;/p&gt;
&lt;p&gt;同时，如果管理认为确实存在违规，将会对内容进行删除。如果此用户在最近时间内多次违反社区规范，严重者进行封禁处理。&lt;/p&gt;
&lt;h3&gt;上传图片和发送表情&lt;/h3&gt;
&lt;p&gt;上传图片（黄色箭头）发送表情（红色箭头）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1740804898094.png&quot; alt=&quot;1740804898094&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;修改头像&lt;/h3&gt;
&lt;p&gt;按照图中标号顺序进行操作即可&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1740805059824.png&quot; alt=&quot;1740805059824&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;修改主页背景图&lt;/h3&gt;
&lt;p&gt;按照图中标号顺序进行操作即可&lt;/p&gt;
&lt;p&gt;（我测试的时候发现某些图片上传后会报错，但是始终没有找出是因为什么。但是换一张图就好了，玄学得很。。。）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1740805074641.png&quot; alt=&quot;1740805074641&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;经验系统&lt;/h3&gt;
&lt;h4&gt;增加经验&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;发表帖子随机增加 10~40 经验&lt;/li&gt;
&lt;li&gt;发表回复随机增加 5~30 经验&lt;/li&gt;
&lt;li&gt;受到点赞随机增加 5~15 经验&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;经验记录&lt;/h4&gt;
&lt;p&gt;如下图操作即可：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1741011075303.png&quot; alt=&quot;1741011075303&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;经验等级&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;等级名称&lt;/th&gt;
&lt;th&gt;所需经验值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;150&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;250&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;350&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;450&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;550&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;650&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;700&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;750&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;850&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;900&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;950&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;1050&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;1100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;1150&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;1200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;1250&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;1300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;1350&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;1400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;1450&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;1500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;1600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;1700&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;1800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;1900&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;2000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;2100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;37&lt;/td&gt;
&lt;td&gt;2200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;38&lt;/td&gt;
&lt;td&gt;2300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;39&lt;/td&gt;
&lt;td&gt;2400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;2500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;2650&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;2800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;2950&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;3100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;3250&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;td&gt;3400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;47&lt;/td&gt;
&lt;td&gt;3550&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;3700&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;3850&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;4000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;td&gt;4200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;52&lt;/td&gt;
&lt;td&gt;4400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;53&lt;/td&gt;
&lt;td&gt;4800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;54&lt;/td&gt;
&lt;td&gt;5000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;55&lt;/td&gt;
&lt;td&gt;5500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;td&gt;6500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;td&gt;8000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;58&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;15000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;td&gt;20000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item><item><title>社区规范</title><link>https://blog.mitufun.top/posts/%E7%A4%BE%E5%8C%BA%E8%A7%84%E8%8C%83/</link><guid isPermaLink="true">https://blog.mitufun.top/posts/%E7%A4%BE%E5%8C%BA%E8%A7%84%E8%8C%83/</guid><description>社区规范</description><pubDate>Sat, 04 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;社区规范&lt;/h2&gt;
&lt;h3&gt;总则&lt;/h3&gt;
&lt;p&gt;欢迎大家加入&lt;strong&gt;韭菜鸡蛋墙&lt;/strong&gt;！为了维护良好的交流环境，确保所有同学都能愉快、安全地使用墙，特制定以下规范。所有同学在使用墙时，必须遵守本规范及相关法律法规。&lt;/p&gt;
&lt;h3&gt;言论规范&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;遵守法律法规&lt;/strong&gt;：不得发布违反国家法律法规的信息，包括但不限于政治敏感内容、非法交易、暴力恐怖、涉黄涉毒等内容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;尊重他人&lt;/strong&gt;：不得发布侮辱、诽谤、骚扰、歧视、挑衅、恶意攻击他人的内容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;禁止网络暴力&lt;/strong&gt;：不得煽动、参与或助长针对任何个人或群体的网络暴力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;杜绝造谣与虚假信息&lt;/strong&gt;：不得发布未经证实的消息，恶意散播谣言，或误导他人。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文明用语&lt;/strong&gt;：不得使用低俗、辱骂、猥亵、恐吓性语言。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;禁止恶意刷屏&lt;/strong&gt;：不得通过重复发帖、无意义内容等方式干扰社区正常交流。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;内容发布规范&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;主题明确&lt;/strong&gt;：发帖须符合社区主题，禁止无关或恶意广告。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;尊重版权&lt;/strong&gt;：禁止发布侵犯他人知识产权的内容，如未经授权的文章、图片、音视频等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;真实可靠&lt;/strong&gt;：发布商品、服务等交易信息时，请确保真实，不得虚假宣传或诈骗。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;禁止恶意引战&lt;/strong&gt;：不得发表煽动性言论，制造对立、破坏社区和谐。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;交易与责任&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;交易自愿原则&lt;/strong&gt;：社区内的所有交易均为用户之间的自愿行为，社区仅作为信息发布平台。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;谨慎辨别信息&lt;/strong&gt;：用户在购买或出售商品、服务时，应自行判断其真实性和可靠性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;风险自负&lt;/strong&gt;：因交易产生的任何纠纷、损失，由交易双方自行承担，社区不负任何责任。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;管理与处罚&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;违规处理&lt;/strong&gt;：对于违反本规范的行为，管理员有权删除违规内容、限制发言、封禁账号等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;严重违规处罚&lt;/strong&gt;：对于严重违反本规范、影响社区秩序或对他人造成严重伤害的用户，管理员有权&lt;strong&gt;封禁账号&lt;/strong&gt;，并在必要情况下向学校相关部门&lt;strong&gt;反映情况&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;举报机制&lt;/strong&gt;：鼓励用户举报违规内容，经核实后将采取相应措施。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最终解释权&lt;/strong&gt;：墙有权根据实际情况对本规范进行修订，并保留最终解释权。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;免责声明&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;本社区仅提供交流平台，所有用户言论仅代表个人观点，不代表本社区的立场。&lt;/li&gt;
&lt;li&gt;任何因使用本社区而产生的直接或间接损失，本社区不承担任何责任。&lt;/li&gt;
&lt;li&gt;若用户违反本规范导致法律后果，责任由用户本人承担。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;感谢大家共同维护一个友善、理性、积极的网络环境！&lt;/p&gt;
</content:encoded></item></channel></rss>