[{"content":"Aminiam\u0026rsquo;s Blog Page 倉庫 fork 自 stack。\n這裏記錄了 Aminiam 的筆記、心得和可以公開的寫作。\n所有原創的 Post 內容 Aminiam 保留所有權利，具體開源證書請查看 LICENSE。\n","date":"2026-08-18T19:14:46+08:00","image":"/p/hello-world/Columbina.png","permalink":"/p/hello-world/","title":"Hello World"},{"content":"External Images are not allowed. Okay I will not import external images.\nAminiam keeps this just as a reminder.\nLet me paste my avatar here cuz idk what to put in the gallary.\n","date":"2026-08-18T19:23:13+08:00","image":"/p/image-gallery/cover.jpg","permalink":"/p/image-gallery/","title":"Image Gallery"},{"content":"C可變參數解包 示例：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include \u0026lt;stdio.h\u0026gt; #include \u0026lt;stdarg.h\u0026gt; int sum(int n, ...) { va_list ap; va_start(ap, n); int ans = 0; for (int i = 0; i \u0026lt; n; ++i) ans += va_arg(ap, int); va_end(ap); return ans; } int main() { printf(\u0026#34;%d\\n\u0026#34;, sum(4, 1, 3, 5, 7)); return 0; } 1 16 C++ 可變參數模板與遞歸解包 方式一：遞歸解包 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include \u0026lt;iostream\u0026gt; using namespace std; template\u0026lt;typename T\u0026gt; T maxn(T a) { return a; } template\u0026lt;typename T, typename... Args\u0026gt; T maxn(T a, Args... rest) { T b = maxn(rest...); return a \u0026gt; b ? a : b; } int main() { cout \u0026lt;\u0026lt; maxn\u0026lt;double\u0026gt;(1.1, 2.2, 3.3) \u0026lt;\u0026lt; endl; return 0; } 方法二：摺疊表達式 類型 寫法 展開結果 一元左摺疊 (... + args) ((a + b) + c) 一元右摺疊 (args + ...) (a + (b + c)) 二元左摺疊 (0 + ... + args) (((0 + a) + b) + c) 二元右摺疊 (args + ... + 0) (a + (b + (c + 0))) 示例：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include \u0026lt;iostream\u0026gt; using namespace std; template\u0026lt;typename T, typename... Args\u0026gt; T maxn(T a, Args... args) { ((a = a \u0026gt; args ? a : args), ...); return a; } int main() { cout \u0026lt;\u0026lt; maxn\u0026lt;double\u0026gt;(1.1, 2.2, 3.3, 4.4) \u0026lt;\u0026lt; endl; return 0; } 完美轉發 1 2 3 4 5 6 7 #include \u0026lt;utility\u0026gt; template\u0026lt;typename T\u0026gt; void wrapper(T\u0026amp;\u0026amp; x) { process(std::forward\u0026lt;T\u0026gt;(x)); } 1 2 template\u0026lt;typename... Args\u0026gt; void print(Args\u0026amp;\u0026amp;... args) { std::cout \u0026lt;\u0026lt; ... \u0026lt;\u0026lt;\u0026lt; std::forward\u0026lt;Args\u0026gt;(args) } ","date":"2026-10-09T14:49:53+08:00","permalink":"/p/c-cpp-args/","title":"C CPP 解包"},{"content":"C register\nvolatile：指定變量可能被外部修改，每次都應重新讀取，不應相信緩存\n1.5: double, 1.5f: float, 1.5L: long double\nfabs(x - y) \u0026lt; \\varepsilon $\\leftrightarrow$ $|x - y| \u0026lt;\\varepsilon$; fabs(x - y) \u0026lt; fabs(x * \\varepsilon) $\\leftrightarrow$ $|x-y|\u0026lt;|x|\\varepsilon$\n轉義字符：\n字符 含義 \\b backspace \\r 回車，光標移動到行首 \\t tab \\v vertical tab \\f 走紙換頁 \\\\ \\\u0026quot; \\' \\ddd 三位八進制 \\xdd 兩位十六進制 格式輸入輸出\n逗號表達式：從左向右依次計算，最後一個表達式的值作爲表達式運算的結果\n只有一元、三元、賦值運算的結合性爲從右向左\n隱式轉換規則：short, char -\u0026gt; int -\u0026gt; unsigned int -\u0026gt; long -\u0026gt; unsigned long -\u0026gt; float -\u0026gt; double -\u0026gt; long double\n字符串拼接：\n方式一：'\\'自動拼接\n方式二：\u0026ldquo;A \u0026ldquo;\u0026ldquo;B\u0026rdquo; = \u0026ldquo;A B\u0026rdquo;：相連的字符串常量自動拼接\nscanf(\u0026quot;%d\u0026quot;, s)會在空格中止，gets(s)會在行尾中止\n\u0026lt;cstring\u0026gt;:\nfunction def strlen() strcpy(s1, s2) s2複製到s1 strncpy(s1, s2, n) 將s2中前n個字符複製到s1 strcat(s1, s2) 將s2追加到s1中 strcmp(s1, s2) 返回字典序s1 \u0026gt; s2 ? : strlwr(s) 覆寫s爲lowercase strupr(s) 覆寫s爲uppercase puts(s) printf(\u0026quot;%s\u0026quot;, s) gets() ","date":"2026-09-17T13:55:05+08:00","permalink":"/p/c-notes/","title":"Notes for C"},{"content":"Pandas Basics Here we import numpy, pandas as:\n1 2 import numpy as np import pandas as pd Basic data structures in pandas pandas provides two types of classes fro handling data:\nSeries: a one-dimansional labeled array holding data of any type, such as integers, strings, Python objects, etc.\nDataFrame: a two-dimensional data structure that holds data like a two-dimension array or a table with rows and columns.\nObject creation Creating a Series by passing a list of values, letting pandas create a default RangeIndex\n1 2 3 4 5 6 7 8 9 10 11 \u0026gt;\u0026gt;\u0026gt; import numpy as np \u0026gt;\u0026gt;\u0026gt; import pandas as pd \u0026gt;\u0026gt;\u0026gt; s = pd.Series([1, 3, 5, np.nan, 6, 8]) \u0026gt;\u0026gt;\u0026gt; s 0 1.0 1 3.0 2 5.0 3 NaN 4 6.0 5 8.0 dtype: float64 Creating a DataFrame by passing a NumPy array with a datetime index using date_range() and labeled columns:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 \u0026gt;\u0026gt;\u0026gt; dates = pd.date_range(\u0026#34;20260909\u0026#34;, periods=6) \u0026gt;\u0026gt;\u0026gt; dates DatetimeIndex([\u0026#39;2026-09-09\u0026#39;, \u0026#39;2026-09-10\u0026#39;, \u0026#39;2026-09-11\u0026#39;, \u0026#39;2026-09-12\u0026#39;, \u0026#39;2026-09-13\u0026#39;, \u0026#39;2026-09-14\u0026#39;], dtype=\u0026#39;datetime64[ns]\u0026#39;, freq=\u0026#39;D\u0026#39;) \u0026gt;\u0026gt;\u0026gt; df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list(\u0026#34;ABCD\u0026#34;)) \u0026gt;\u0026gt;\u0026gt; df A B C D 2026-09-09 0.956212 0.496608 1.031761 0.439333 2026-09-10 -0.283260 0.644414 -0.352740 -0.617138 2026-09-11 0.667249 1.570810 -1.711173 1.114610 2026-09-12 -0.324996 -0.441097 0.821568 -0.425018 2026-09-13 0.981316 0.504753 1.098882 0.498294 2026-09-14 0.433741 0.992282 -0.737600 1.621099 ","date":"2026-09-09T11:30:40+08:00","permalink":"/p/pandas-notes/","title":"Notes for Pandas"},{"content":"Pyplot Basics Introduction to pyplot matplotlib.pyplot is a collection of functions that make matplotlib work like MATLAB. Each pyplot function makes some change to a figure: e.e., creates a figure, creates a plotting area in a figure, plots some lines in a plotting area, decorates the plot with labels, etc.\nIn matplotlib.pyplot various states are preserved across function calls, so that it keeps track of things like the current figure and plotting area, and the plotting functions are directed to the current Axes (please note that we user uppercase Axes to refter to the Axes concept, which is a central part of a figure and not only the plural of axis).\n1 2 3 4 import matplotlib.pyplot as plt plt.plot([1, 3, 3, 4]) plt.ylabel(\u0026#39;some numbers\u0026#39;) plt.show() If your provide a single list or array to plot, matplotlib assumes it i a sequence of y values, and automatically generates the x values for you. Since python ranges start with 0, the default x vector has the same length as y but starts with 0; there fore, the x data are [0, 1, 2, 3].\nplot is a versatile function, and will take an arbitrary number of arguments. For example, to plot x versus y, you can write:\n1 plt.plot([1, 2, 3, 4], [1, 4, 9, 16]) Formatting the style of you plot For every x, y pair of arguments, there is an optional third argument which is the format string that indicates the color and line type of the plot. The letters and symbols of the format string are from MATLAB, and you concatenate a color string with a line style string. The default format string is \u0026lsquo;b-\u0026rsquo;, which is a solid blue line. For example, to plot the above with red circles, you would issue.\n1 2 3 plt.plot([1, 2, 3, 4], [1, 4, 9, 16], \u0026#39;ro\u0026#39;) plt.axis((0, 6, 0, 20)) plt.show() The axis function in the example above takes a list of [xmin, xmax, ymin, ymax] and specifies the viewport of the Axes.\nGenerally, you will use numpy arrays.\n1 2 3 4 5 6 import numpy as np # evenly sampled time at 200ms intervals t = np.arange(0., 5., 0.2) # red dashes, blue squares and green triangles plt.plot(t, t, \u0026#39;r--\u0026#39;, t, t**2, \u0026#39;bs\u0026#39;, t, t**3, \u0026#39;g^\u0026#39;) plt.show() Plot with keyword strings There are some instances where you have data in a format theat lets you access particular variables with strings. For example, with strctured arrays or pandas.DataFrame.\nMatplotlib allows you to provide such an object with the data keyword argument. I fprovided, the you may generate plots with the strings corresponding to these variables.\n1 2 3 4 5 6 7 8 9 data = {\u0026#39;a\u0026#39;: np.arange(50), \u0026#39;c\u0026#39;: np.random.randint(0, 50, 50), \u0026#39;d\u0026#39;: np.random.randn(50)} data[\u0026#39;b\u0026#39;] = data[\u0026#39;a\u0026#39;] + 10 * np.random.randn(50) data[\u0026#39;d\u0026#39;] = np.abs(data[\u0026#39;d\u0026#39;]) * 100 plt.scatter(\u0026#39;a\u0026#39;, \u0026#39;b\u0026#39;, c=\u0026#39;c\u0026#39;, s=\u0026#39;d\u0026#39;, data=data) plt.xlabel(\u0026#39;entry a\u0026#39;) plt.ylabel(\u0026#39;entry b\u0026#39;) plt.show() Plotting with categorical variables It is also possible to create a plot using categorical variables. Matplotlib allows you to pass categorical variables directly to many plotting functions. For example:\n1 2 3 4 5 6 7 8 9 10 11 names = [\u0026#39;group_a\u0026#39;, \u0026#39;group_b\u0026#39;, \u0026#39;group_c\u0026#39;] values = [1, 10, 100] plt.figure(figsize=(9, 3)) plt.subplot(131) plt.bar(names, values) plt.subplot(132) plt.scatter(names, values) plt.subplot(133) plt.plot(names, values) plt.suptitle(\u0026#39;Categorical Plotting\u0026#39;) plt.show() Controlling line properties Lines have many attributes that you can set: linewidth, dash style, antialiased, etc. There are several ways to set line properties:\nUse keyword arguments 1 plt.plot(x, y, linewidth=2.0) Use the setter methods of a Line2D instance. plot returns a list of Line2D objects; e.g., line1, line2 = plot(x1, y1, x2, y2). In the code below we will suppose that we have only one line so that the list returned is of length 1. We use tuple unpacking with line, to get the first element of that list: 1 2 line, = plt.plot(x, y, \u0026#39;-\u0026#39;) line.set_antialiased(False) # turn off antialiasing Use setp. The example below uses a MATLAB-style function to set multiple properties on a list of lines. setp works transparently with a list of objects or a single object. You can either use python keyword arguments or MATLAB-style string/value pairs: 1 2 3 4 5 lines = plt.plot(x1, y1, x2, y2) # use keyword arguments plt.setp(lines, color=\u0026#39;r\u0026#39;, linewidth=2.0) # or MATLAB style string value pairs plt.setp(lines, \u0026#39;color\u0026#39;, \u0026#39;r\u0026#39;, \u0026#39;linewidth\u0026#39;, 2.0) More in Matplotlib.Line2D\nWorking with multiple figures and Axes MATLAB, and pyplot, have the concept of the current figure and the current Axes. All plotting functions apply to the current Axes. The gunction gca returns the current figure (A matplotlib.axes.Axes instance), and gcf returns the current figure (a matplotlib.figure.Figure instance). Normally, you don\u0026rsquo;t have to worry about this, becase it is all taken care of behind the scenes. Below is a script to create two subplots.\n1 2 3 4 5 6 7 8 9 10 def f(t): return np.exp(-t) * np.cos(2 * np.pi * t) t1 = np.arange(0.0, 5.0, 0.1) t2 = np.arange(0.0, 5.0, 0.02) plt.figure() plt.subplot(211) plt.plot(t1, f(t1), \u0026#39;bo\u0026#39;, t2, f(t2), \u0026#39;k\u0026#39;) plt.subplot(212) plt.plot(t2, np.cos(2 * np.pi * t2), \u0026#39;r--\u0026#39;) plt.show() The figure call here is optional because a figure will be created if none exists, just as an Axes will be created (equivalent to an explicit subplot() call) if none exists. The subplot call specifies numrows, numcols, plot_number where plot_number ranges from 1 to numrowsnumcols. The commas in the subplot call are optional if numrowsnumcols\u0026lt;10. So subplot(211) is identical to subplot(2, 1, 1).\n1 2 3 4 5 plt.subplot( [nrows](n rows of plots will be created), [ncols](n cols of plots will be created), [index](start from 1, L2R, T2B) ) You can create an arbitrary number of subplots and Axes. If you want to place an Axes manually, i.e., not on a rectangular grid, use axes, which allows you to specify the location as axes([left, bottom, width, height]) where all values are in fractional (0 to 1) coordinates. See Axes Demo for an example of placing Axes manually and Multiple subplots for an example with lots of subplots.\nYou can create multiple figures by using multiple figure calls with an increasing figure number. Of course, each figure can contain as many Axes and subplots as your heart desires:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import matplotlib.pyplot as plt plt.figure(1) # the first figure plt.subplot(211) # the first subplot in the first figure plt.plot([1, 2, 3]) plt.subplot(212) # the second subplot in the first figure plt.plot([4, 5, 6]) plt.figure(2) # a second figure plt.plot([4, 5, 6]) # creates a subplot() by default plt.figure(1) # first figure current; # subplot(212) still current plt.subplot(211) # make subplot(211) in the first figure # current plt.title(\u0026#39;Easy as 1, 2, 3\u0026#39;) # subplot 211 title You can clear the current figure with clf and the current Axes with cla. If you find it annoying that states (specifically the current image, figure and Axes) are being maintained for you behind the scenes, don\u0026rsquo;t despair: this is just a thin stateful wrapper around an object-oriented API, which you can use instead (see Artist tutorial)\nIf you are making lots of figures, you need to be aware of one more thing: the memory required for a figure is not completely released until the figure is explicitly closed with close. Deleting all references to the figure, and/or using the window manager to kill the window in which the figure appears on the screen, is not enough, because pyplot maintains internal references until close is called.\nWorking with text text can be used to add text in an arbitrary location, and xlabel, ylabel and title are used to add text in the indicated locations.\n1 2 3 mu, sigma = 100, 15 x = mu + sigma * np.random.randn(10000) # the histogram // TODO from here MATLAB format string 1 plt.plot(x, y, fmt) here:\n1 fmt = \u0026#39;[marker][line][color]\u0026#39; Marker styles Code Marker Meaning . point small dot o circle ○ s square □ ^ triangle up △ v triangle down ▽ \u0026lt; triangle left \u0026gt; triangle right * star ★ + plus + x cross × D diamond ◇ Line styles Code Style Appearance - solid ━━━━━ -- dashed - - - - -. dash-dot -·-·- : dotted ····· Colour codes Code Colour Example b blue 'b' g green 'g' r red 'r' c cyan 'c' m magenta 'm' y yellow 'y' k black 'k' w white 'w' 序列解包 1 line, = plt.plot(x, y, \u0026#39;-\u0026#39;) plt.plot()返回一个列表，其中包含所绘制的line2D对象（即使只有一条线，也是长度为$1$的列表）\nline,是一个单元素元组（逗号作为必须的标识符），它要求右侧的可迭代对象恰好有一个元素\n解包过程将列表中的唯一一个line2D对象提取出来，赋值给line\n等价于：\n1 line = plt.plot(x, y, \u0026#39;-\u0026#39;)[0] ","date":"2026-09-05T10:13:30+08:00","permalink":"/p/matplotlib-notes/","title":"Notes for Matplotlib"},{"content":"層次分析法 AHP（Analytic Hierarchy Process） 問題背景 決策目標涉及多個難以統一量綱衡量的因素時，需要有一種方法把專家的主管判斷轉化爲客觀權重。\n與其直接問某因素的權重，不如讓專家兩兩比較“A比B”重要多少倍。\n兩兩比較的結果構成判斷矩陣$(A_{ij}) _ {n\\times n}$，其中$a_{ij}$表示因素$i$相對於$j$的重要程度，採用如下標度法：\n標度 含義 1 同等重要 3 稍微重要 5 明顯重要 7 強烈重要 9 極端重要 2,4,6,8 中間值 性質 矩陣滿足互反性：$a_{ij}a_{ji}=1$，對角線$a_{ii}=1$\n若專家的判斷具有完全一致性，則存在權重向量$(\\omega)_n$使得：\n$$ a_{ij} = \\frac{\\omega_i}{\\omega_j} $$ 此時矩陣$A$可以寫成列向量與行向量的乘積形式。\n下面證明權重向量就是特徵向量：\n$$ (A\\omega)_i=\\sum_j{a_{ij}\\omega_j}=n\\omega_i\\space\\square $$ 現實中專家判斷難免有偏差，矩陣不完全已知，但可以證明此時最大的特徵值$\\lambda_{max}\\ge n$，且當$\\lambda_{max}$越接近$n$，矩陣一致性越好。於是去最大特徵值對應的特徵向量，歸一化後作爲權重。\n一致性檢驗 定義一致性指標：\n$$ CI=\\frac{\\lambda_{max}-n}{n-1} $$ 再用隨機一致性指標$RI$（查表可知，反映隨機矩陣的平均$CI$）做歸一化：\n$$ CR=\\frac{CI}{RI} $$ 當$CR\u0026lt;0.1$認爲矩陣一致性可以接受。\nPython實現 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import numpy as np def ahp_analysis(A): n = A.shape[0] eigvals, eigvecs = np.linalg.eig(A) # 計算特徵值和特徵向量 max_idx = np.argmax(eigvals.real) # 數值計算可能有小虛部，並找到最大特徵值位置 lambda_max = eigvals[max_idx].real # 提取最大特徵值 w = eigvecs[:, max_idx].real # 提取對應特徵向量 weights = w / w.sum() # 歸一化 # 一致性檢驗： CI = (lambda_max - n) / (n - 1) RI_table = {1:0, 2:0, 3:0.58, 4:0.90, 5:1.12, 6:1.24, 7:1.32, 9:1.41} RI = RI_table[n] CR = CI / RI # return return weights, CR 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 \u0026gt;\u0026gt;\u0026gt; import numpy as np \u0026gt;\u0026gt;\u0026gt; A = np.array([[1, 3, 1.0 / 3.0], [1.0 / 3.0, 1\\ , 1.0 / 5.0], [3, 5, 1]]) \u0026gt;\u0026gt;\u0026gt; n = A.shape[0] \u0026gt;\u0026gt;\u0026gt; eigvals, eigvecs = np.linalg.eig(A) \u0026gt;\u0026gt;\u0026gt; print(eigvals) [ 3.03851109+0.j -0.01925555+0.34153419j -0.01925555-0.34153419j] \u0026gt;\u0026gt;\u0026gt; print(eigvecs) [[ 0.37147738+0.j 0.18573869-0.32170885j 0.18573869+0.32170885j] [ 0.1506267 +0.j 0.07531335+0.13044655j 0.07531335-0.13044655j] [ 0.916142 +0.j -0.916142 +0.j -0.916142 -0.j ]] \u0026gt;\u0026gt;\u0026gt; max_idx = np.argmax(eigvals.real) \u0026gt;\u0026gt;\u0026gt; print(max_idx) 0 \u0026gt;\u0026gt;\u0026gt; lambda_max = eigvals[max_idx].real \u0026gt;\u0026gt;\u0026gt; print(lambda_max) 3.0385110905581696 \u0026gt;\u0026gt;\u0026gt; w = eigvecs[:, max_idx].real \u0026gt;\u0026gt;\u0026gt; print(w) [0.37147738 0.1506267 0.916142 ] \u0026gt;\u0026gt;\u0026gt; weights = w / w.sum() \u0026gt;\u0026gt;\u0026gt; print(weights) [0.25828499 0.10472943 0.63698557] \u0026gt;\u0026gt;\u0026gt; CI = (lambda_max - n) / (n - 1) \u0026gt;\u0026gt;\u0026gt; print(CI) 0.019255545279084796 \u0026gt;\u0026gt;\u0026gt; RI_table = {1:0, 2:0, 3:0.58, 4:0.90, 5:1.12, \\ 6:1.24, 7:1.32, 9:1.41} \u0026gt;\u0026gt;\u0026gt; RI = RI_table[n] \u0026gt;\u0026gt;\u0026gt; CR = CI / RI \u0026gt;\u0026gt;\u0026gt; print(CR) 0.033199215998422064 1 np.argmax(...) // 找到數組中最大值的索引位置 TOPSIS法（逼近理想解排序法） TOPSIS (Tecnique for Order Preference by Similarity to Ideal Solution)\n一個好的方案，應該離最優解情況最近，同時離最差情況最遠。\n性質 設有$m$個評價對象，$n$個指標，決策矩陣爲$X=(x_{ij})_{m\\times n}$。\n正向化：若指標是“越小越好”型，先轉化爲“越大越好”型，常用取倒數或者$max-x$的方式\n歸一化（消除兩綱影響），常用向量歸一化：$\\displaystyle z_{ij}=\\frac{x_{ij}}{\\sqrt{\\sum_{i=1}^m{x_{ij}^2}}}$。\n加權（結合AHP或熵權法得到的權重$\\omega_j$）：$v_{ij}=\\omega_j z_{ij}$。\n確定正負理想解：$Z^+=(\\max_iv_{i1},\\cdots,\\max_iv_{in}$，$Z^+=(\\min_iv_{i1},\\cdots,\\min_iv_{in}$\n計算歐氏距離與貼近度：\n$$ D_i^+=\\sqrt{\\sum_j{(v_{ij}-Z_j^+)^2}} $$$$ D_i^-=\\sqrt{\\sum_j{(v_{ij}-Z_j^-)^2}} $$$$ C_i=\\frac{D_i^-}{D_i^++D_i^-}\\in[0,1] $$ 顯然$C_i$越接近$1$，該方案越優。\nPython實現 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import numpy as np def topsis(data, weights, indicator_types): X = data.astype(float) # 將數據強制轉化成float m, n = X.shape # 1. 正向化（如果是極小性，則翻轉） for j in range(n): if indicator_types[j] == \u0026#39;min\u0026#39;: X[:, j] = np.max(X[:, j]) - (X[:, j]) # 2. 向量歸一化（按列歸一化） norm-factor = np.sqrt(np.sum(X**2, axis=0)) # axis=0是列，1是行 Z = X / norm_factor # 廣播 # 3. 加權 V = Z * weights # 區別@，這裏是對應元素相乘 # 4. 正負理想解 Z_pos = V.max(axis=0) Z_neg = V.min(axis=0) # 5. 計算歐氏距離 D_pos = np.sqrt(np.sum((V - Z_pos)**2, axis=1)) D_neg = np.sqrt(np.sum((V - Z_neg)**2, axis=1)) # 6. 貼近度 C = D_neg / (D_pos + D_neg + 1e-8) # return return C 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 \u0026gt;\u0026gt;\u0026gt; import numpy as np \u0026gt;\u0026gt;\u0026gt; data = np.array([[5, 5, 10], [8, 8, 5]]) \u0026gt;\u0026gt;\u0026gt; weights = [0.25828499, 0.10472943, 0.63698557] \u0026gt;\u0026gt;\u0026gt; X = data.astype(float) \u0026gt;\u0026gt;\u0026gt; m, n = X.shape \u0026gt;\u0026gt;\u0026gt; norm_factor = np.sqrt(np.sum(X**2,axis=0)) \u0026gt;\u0026gt;\u0026gt; Z = X / norm_factor \u0026gt;\u0026gt;\u0026gt; V = Z * weights \u0026gt;\u0026gt;\u0026gt; Z_pos = V.max(axis=0) \u0026gt;\u0026gt;\u0026gt; Z_neg = V.min(axis=0) \u0026gt;\u0026gt;\u0026gt; D_pos = np.sqrt(np.sum((V - Z_pos)**2, axis=1)\\ ) \u0026gt;\u0026gt;\u0026gt; D_neg = np.sqrt(np.sum((V - Z_neg)**2, axis=1)\\ ) \u0026gt;\u0026gt;\u0026gt; C = D_neg / (D_pos + D_neg + 1e-8) \u0026gt;\u0026gt;\u0026gt; print(C) [0.76270391 0.23729606] 最小二乘擬合與迴歸 性質 設擬合模型爲$\\hat{y}=P_k(x)=\\sum_i\\beta_ix^k$，定義殘差平方和：\n$$ S(\\beta) = \\sum_i(y_i-\\hat{y}_i)^2 $$ 最小二乘法的目標是找到使$S(\\beta)$最小的參數$\\beta$。\n推導正規方程：將模型寫作$y=X\\beta+\\varepsilon$，其中$X$是範德蒙德矩陣（每行爲：$[1,x_i,x_i^2,\\cdots,x_i^k]$），展開$S(\\beta)$：\n$$ S(\\beta)=(y-X\\beta)^T(y-X\\beta)=y^Ty-2\\beta^TX^Ty+\\beta^TX^TX\\beta $$ 對$\\beta$求梯度並令其爲零：\n$$ \\frac{\\partial S}{\\partial\\beta}=-2X^Ty+2X^TX\\beta=0 $$ 解得正規方程：\n$$ X^TX\\beta=X^Ty $$ 當$X$列滿秩時，$\\beta=(X^TX)^{-1}X^Ty$\n證明其最優性（高斯-馬爾可夫定理，BLUE）：略\nPython實現 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 import numpy as np class LinearRegression: def __init__(self): self.coef_ = None self.intercept_ = None self.r2_ = None def fit(self, X, y): # X: （樣本數，特徵數），y: （樣本數，） # 構造增廣矩陣：在X左邊加一列1，用來計算解決 X_design = np.c_[np.ones(X.shape[0]), X] beta = np.linalg.inv(X_design.T @ X_design) @ X_design.T @ y self.intercept_ = beta[0] self.coef_ = beta[1:] y_pred = self.predict(X) ss_res = np.sum((y - y_pred)**2) ss_tot = np.sum((y - np.mean(y))**2) self.r2_ = 1 - ss_res / ss_tot return self def predict(self, X): return X @ self.coef_ + self.intercept_ 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 import numpy as np # 一维数组（形状: (3,) ） a1 = np.array([1, 2, 3]) b1 = np.array([4, 5, 6]) # 二维数组（形状: (2, 2) ） a2 = np.array([[1, 2], [3, 4]]) b2 = np.array([[5, 6], [7, 8]]) # 第一部分：按列左右拼接 (Horizontal / 增加列数) # np.hstack —— 对一维数组：保持一维，直接延长（拼接元素） res_hstack_1d = np.hstack((a1, b1)) # 输出: [1 2 3 4 5 6] (6,) # np.c_ —— 对一维数组：转成列向量，形成二维矩阵（增加列数） # 相当于把 a1 和 b1 看作两列特征，形状从 (3,) + (3,) -\u0026gt; (3, 2) res_c_1d = np.c_[a1, b1] # 输出: [[1 4] (3, 2) # [2 5] # [3 6]] # np.column_stack —— 和 np.c_ 效果完全一样（一维数组当列处理） res_col_stack = np.column_stack((a1, b1)) print(f\u0026#34;column_stack 一维结果: \\n{res_col_stack}, 形状: {res_col_stack.shape}\u0026#34;) # 针对二维数组：hstack、c_、concatenate(axis=1) 三者等价 res_hstack_2d = np.hstack((a2, b2)) res_c_2d = np.c_[a2, b2] res_concat_axis1 = np.concatenate((a2, b2), axis=1) # axis=1 代表列方向 {res_hstack_2d.shape}\u0026#34;) # 输出: [[1 2 5 6] (2, 4) # [3 4 7 8]] # 不要对一维数组用 concatenate(axis=1)，因为一维没有 axis=1 维度 # np.vstack —— 对一维数组：转成行向量，上下堆叠（增加行数） # 相当于把 a1 和 b1 看作两行样本，形状从 (3,) + (3,) -\u0026gt; (2, 3) res_vstack_1d = np.vstack((a1, b1)) # 输出: [[1 2 3] (2, 3) # [4 5 6]] # np.r_ —— 对一维数组：直接合并延长（和 vstack 不同！r_ 对一维是延长） # r_ 对一维数组的行为是“合并元素”，类似 hstack（特殊） res_r_1d = np.r_[a1, b1] # 输出: [1 2 3 4 5 6] (6,) # 针对二维数组：vstack、r_、concatenate(axis=0) 三者等价 res_vstack_2d = np.vstack((a2, b2)) res_r_2d = np.r_[a2, b2] res_concat_axis0 = np.concatenate((a2, b2), axis=0) # axis=0行方向（默认值） # 输出: [[1 2] (4, 2) # [3 4] # [5 6] # [7 8]] # np.row_stack —— np.vstack 的别名 res_row_stack = np.row_stack((a2, b2)) # 增加新维度拼接 (np.stack) # np.stack 会在指定位置创建一个新的维 res_stack_axis0 = np.stack((a1, b1), axis=0) # 新维度在第0层（第0轴变成2） res_stack_axis1 = np.stack((a1, b1), axis=1) # 新维度在第1层（第1轴变成2） # 输出: [[1 2 3] (2, 3) # [4 5 6]] # 输出: [[1 4] (3, 2) # [2 5] # [3 6]] 1 2 3 X.T # 转置 np.linalg.inv() # 求逆 x.reshape(-1, 1) # 将一维数组变成二维列向量。`-1`表示自动计算行数 ","date":"2026-09-02T21:35:33+08:00","permalink":"/p/mcm-skills/","title":"MCM 常用方法 Python 版"},{"content":"一、格式说明符 格式符 printf 参数类型 scanf 参数类型 说明 %d int int* 十进制有符号整数 %u unsigned int unsigned int* 十进制无符号整数 %o unsigned int unsigned int* 八进制 %x unsigned int unsigned int* 十六进制（小写） %X unsigned int unsigned int* 十六进制（大写） %f double float* 浮点数（printf 用 %f/%lf 均可，scanf 必须 %f 给 float，%lf 给 double） %e double float* 科学计数法（小写 e） %g double float* 自动选 %f 或 %e（较短） %c char char* 单个字符 %s const char* char[] 字符串（遇空白停止） %p const void* void** 指针地址（十六进制） %n int* int* 写入已输出/读取的字符数 %% - - 输出字面量 % 二、长度修饰符 修饰符 适用类型示例 格式 hh signed char / unsigned char %hhd, %hhu h short / unsigned short %hd, %hu l long / unsigned long %ld, %lu ll long long / unsigned long long %lld, %llu L long double %Lf, %Le z size_t %zd t ptrdiff_t %td 三、printf常用标志 标志 作用 示例（%后加标志） - 左对齐（默认右对齐） %-10d + 强制显示正负号 %+d 空格 正数前加空格 % d # 八进制前加0，十六进制加0x/0X，浮点数强制小数点 %#o, %#x, %#f 0 用 0 填充宽度（而非空格） %08d 四、宽度与精度 格式 含义 示例 %最小宽度d 输出至少占 n 位，不足补空格 %5d %.精度f 小数位数（浮点）/ 最大字符数（字符串）/ 最少数字位数（整数） %.2f, %.5s %*.*f 宽度和精度由参数提供 printf(\u0026quot;%*.*f\u0026quot;, w, p, val); 五、scanf 特殊用法 用法 说明 示例 * 抑制赋值（跳过） scanf(\u0026quot;%*d %d\u0026quot;, \u0026amp;n); [集合] 只读指定字符集 %[a-z]（读小写字母） [^] 读直到遇到某字符 %[^,]（读逗号前） ","date":"2026-09-02T13:59:38+08:00","permalink":"/p/printf-scanf-format/","title":"`printf` `scanf` Format Quick Lookup"},{"content":"CPP Builtin 1. 位运算与计数 函数 功能描述 示例 注意 __builtin_popcount(x) 返回 x 的二进制中 1 的个数 __builtin_popcount(15) → 4 有 popcountl、popcountll 版本 __builtin_clz(x) 返回从最高位开始的前导零个数 __builtin_clz(1)（32位）→ 31 传入 0 是 未定义行为；有 clzl、clzll __builtin_ctz(x) 返回从最低位开始的尾随零个数 __builtin_ctz(8) → 3 传入 0 是 未定义行为；有 ctzl、ctzll __builtin_ffs(x) 返回最低位 1 的位置（从 1 开始） __builtin_ffs(8) → 4 x=0 时返回 0；有 ffsl、ffsll __builtin_parity(x) 返回 1 的个数的奇偶性（奇数个1→1） __builtin_parity(15) → 0 有 parityl、parityll 2. 算术运算与安全 函数 功能描述 示例 注意 __builtin_add_overflow(a, b, \u0026amp;res) 安全加法，检测是否溢出 溢出返回 true，否则存入 res 并返回 false 支持 sub（减法）和 mul（乘法） __builtin_abs(x) 等 计算整数或浮点数的绝对值 __builtin_abs(-10) → 10 有 labs、llabs、fabs 等版本 3. 优化与调试 函数 功能描述 示例 注意 __builtin_expect(exp, c) 提供分支预测信息，优化代码布局 常与 if 结合，如 if (__builtin_expect(ptr == nullptr, 0)) 错误使用可能降低性能 __builtin_trap() 强制执行陷阱指令，程序异常终止 用于不应执行到的代码路径 – __builtin_unreachable() 告诉编译器某路径永远不会执行，辅助优化 常用于 switch 的 default 分支（当所有情况已覆盖） – ","date":"2026-09-02T13:52:32+08:00","permalink":"/p/cpp-built-in/","title":"CPP __Builtin_"},{"content":"Sudoku Solver LeetCode 原题地址：37. Sudoku Solver\n狀態壓縮：Bitmask 使用$9$位的二進制整數分別表示$1\\to9$。\n標記佔用：rows[r] |= (1 \u0026lt;\u0026lt; (d - 1))\n撤銷佔用：rows[r] ^= (1 \u0026lt;\u0026lt; (d - 1))\n計算候選數：used = rows[r] | cols[c] | boxes[b]，那麼可用數字：available = (~used) \u0026amp; 0b111111111（取反後保留低$9$位）\nMRV(Minimum Remaining Values)：最小剩餘值啓發式 先填最難的。\n比如：有一個空格，行裏缺{1, 2}，列裏缺{1, 2, 3}，宮裏缺{1}（唯一解），就優先填它。\n這是在“最受限”的位置做決策。如果唯一解的地方都填錯了，說明之前的選擇有無，可以儘早回溯（Fail-First 原則）。反之如果先去填有$9$可能的空格，會浪費大量算力。\n實現方法：在每一層遞歸開始時，掃描所有剩餘空格，找出available裏$1$個數最少的，交換到當前處理位置。\n遍歷方法：位運算提取候選（Lowbit 技巧） 取最低位的1：bit = available \u0026amp; -available\nCount Trailing Zeros：d = __builtin_ctz(bit)\n算法流程：DFS 回溯 初始化：掃描整個棋盤，將已填數字更新到rows，cols，boxes中，同時記錄所有空格座標。\n遞歸入口（backtrack(idx)）\n終止條件：如果idx等於空格總數，說明填完了，返回true。\nMRV 選點：從idx到末尾遍歷所有空格，計算每個空格的available掩碼，統計1的個數，選出最小的那個，並交換到empties[idx]位置。\n嘗試填入：獲取當前空格的available掩碼，利用lowbit去除每一個候選數字。\n放置並遞歸：修改棋盤，更新rows/cols/boxes掩碼，調用backtrack(idx + 1)。\n回溯撤銷：如果遞歸返回false，說明這條路走不通，撤銷掩碼，將棋盤改回'.'，嘗試下一個候選。\n結果：一旦找到解，遞歸棧層層返回true，完成求解。\n實現 emplace_back(r, c)就地構造，push_back(make_pair(r, c))或者push_back({r, c})會產生臨時變量，儘管對於一般的情況會被-O2優化。\nfunction\u0026lt;bool(int)\u0026gt;通用函數包裝器，意爲任意一個接受int參數，並返回bool值的可調用對象（函數、仿函數、Lambda）。\n[\u0026amp;]按引用捕獲，[=]按值捕獲。\nstd::function有微小性能損耗，大約$5%\\to10%$，因爲底層使用了類型擦除，調用時會多一次間接尋址。追求極致可使用auto + Y-Combinator（不動點組合子）來替代以消除開銷。\nidx表示当前处理到第idx个空格。\n1 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 class solution { public: void solveSudoku(vector\u0026lt;vector\u0026lt;char\u0026gt;\u0026gt;\u0026amp; board) { int rows[9] = {0}, cols[9] = {0}, boxes[9] = {0}; vector\u0026lt;pair\u0026lt;int, int\u0026gt;\u0026gt; empties; for (int r = 0; r \u0026lt; 9; ++r) for (int c = 0; c \u0026lt; 9; ++c) if (board[r][c] == \u0026#39;.\u0026#39;) empties.emplace_back(r, c); else { int d = board[r][c] - \u0026#39;1\u0026#39;; int mask = 1 \u0026lt;\u0026lt; d; int b = (r / 3) * 3 + (c / 3); rows[r] |= mask; cols[c] |= mask; boxes[b] |= mask; } function\u0026lt;bool(int)\u0026gt; backtrack = [\u0026amp;](int idx) -\u0026gt; bool { if (idx == empties.size()) return true; int bestIdx = idx; int minCandidates = 10; for (int i = idx; i \u0026lt; empties.size(); ++i) { int r = empties[i].first, c = empties[i].second; int b = (r / 3) * 3 + (c / 3); int used = rows[r] | cols[c] | boxes[b]; int available = (~used) \u0026amp; 0b111111111; int cnt = __builtin_popcount(available); if (cnt \u0026lt; minCandidates) { minCandidates = cnt; bestIdx = i; if (cnt == 1) break; } } if (bestIdx != idx) swap(empties[idx], empties[bestIdx]); int r = empties[idx].first, c = empties[idx].second; int b = (r / 3) * 3 + (c / 3); int used = rows[r] | cols[c] | boxes[b]; int available = (~used) \u0026amp; 0b111111111; while (available) { int bit = available \u0026amp; -available; int d = __builtin_ctz(bit); available ^= bit; board[r][c] = char(\u0026#39;1\u0026#39; + d); rows[r] |= bit; cols[c] |= bit; boxes[b] |= bit; if (backtrack(idx + 1)) return true; board[r][c] = \u0026#39;.\u0026#39;; rows[r] ^= bit; cols[c] ^= bit; boxes[b] ^= bit; } return false; }; backtrack(0); } }; 不動點組合子 經典錯誤寫法：\n1 2 3 4 auto backtrack = [\u0026amp;](int idx) -\u0026gt; bool { if (backtrack(idx + 1)) return true; }; 錯誤因爲backtrack還沒有聲明完，不能在內部調用。\n普通解決方案，用std::function，但是存在性能損耗。\n解決方案核心思想：把自己作爲參數傳遞進去：\n1 2 3 4 5 auto backtrack = [](auto\u0026amp;\u0026amp; self, int idx) -\u0026gt; bool { if (self(self, idx + 1)) return true; return false; }; 左值、右值和萬能引用auto\u0026amp;\u0026amp; 定義 任何一個cpp表達式在編譯器視角都有一下兩個獨立屬性：\n擁有身份（Has Identity）：這個表達式是否代表一塊具體的內存地址？能否用\u0026amp;取到它的地址？\n可被移動（Is Movable）：這個表達式的值是否允許被“竊取”（轉移資源），因爲它馬上就要被銷燬了？\n基於以上兩個不二屬性，表達式分爲三大類：\n左值：Lvalue，有身份\n純右值：Prvalue，沒有（臨時寄存器）\n亡值：Xvalue，有（即將被銷燬的對象）\n右值：Rvalue，純右值或者亡值（要麼沒有地址，要麼瀕臨死亡）\n1 2 3 4 5 6 7 int a = 10; int b = a; // a 是左值，但是出現在等號右邊 \u0026amp;a; // 合法，取左值的地址 \u0026amp;10; // 非法，取右值的地址 // 但可以將右值轉化爲左值（亡值）： int\u0026amp;\u0026amp; c = 10; // 將亡值綁定到右值引用上 \u0026amp;c; // 現在 c 有地址，它是亡值，屬於右值但是可取地址 分析 1 2 auto backtrack = [](auto\u0026amp;\u0026amp; self, int idx) { ... }; backtrack(backtrack, 0); 對於這裏的backtrack：\n這是一個具名變量，編譯器爲它在棧上分配了內存\n它擁有確定的內存地址，可以\u0026amp;backtrack\n它不會在函數調用結束時銷燬（它處於外層作用域）\n因此backtrack是一個左值，傳給auto\u0026amp;\u0026amp;後，推導爲左值引用Type\u0026amp;\n對於0：\n它不佔用靜態或棧上的內存，直接作爲立即數編碼在 CPU 的彙編指令集\n它沒有任何內存地址\n它是一個臨時值，函數調用完就丟棄\n因此0是一個純右值，傳給int indx時發生拷貝\nT\u0026amp;\u0026amp; 情況一：type是具體類型（無推導），這是一個右值引用，會拒絕左值。\n情況二：type是推導佔位符（auto或template T），這是轉發引用，如果傳遞左值，摺疊爲T\u0026amp;，傳入右值，摺疊爲T\u0026amp;\u0026amp;。\nstd::move std::move(a)是類型強轉，對於基礎類型：\n1 2 int a = 1; int b = std::move(a); 執行第二句時，編譯器查找int的構造函數，發現int沒有移動構造函數，於是移動退化爲拷貝，結果是a和b分別指向兩塊內存都儲存了1\n對於資源類型：\n1 2 vector\u0026lt;int\u0026gt; a = {1, 2, 3}; vector\u0026lt;int\u0026gt; b = std::move(a); 執行std::move(a)時a並未改變，執行vector\u0026lt;int\u0026gt; b = std::move(a);時，vector的移動構造函數完成三件事：\n將b指向a本來指向的地址，並將a設置爲nullptr\n將b的大小設置爲a的大小，並將a的大小設置爲0\n將b的容量指向a的容量，並將a的容量歸零\n構造函數初始化列表 節省先构造一个默认空對象再赋值數據的冗餘操作，const成員、引用成員、無默認構造對象必須使用函數初始化列表\n1 2 3 4 5 6 7 8 class Student { private: string name; int age; public: Student(string n, int a) : name(n), age(a) {} }; ","date":"2026-09-02T13:28:15+08:00","permalink":"/p/sudoku-solver/","title":"Sudoku Solver: Bitmask \u0026 MRV"},{"content":"Very Basics The basics NumPy\u0026rsquo;s array class is called ndarray.\nProperties:\nndarray.ndim: dimansions/axes of the arrary.\nndarray.shape: $(x, y, z, t, \\cdots) : tuple?$\nndarray.size: the total number of elements of the array.\nndarray.dtype: ?\nndarray.itemsize: ?\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 \u0026gt;\u0026gt;\u0026gt; import numpy as np \u0026gt;\u0026gt;\u0026gt; a = np.arange(15).reshape(3, 5) \u0026gt;\u0026gt;\u0026gt; a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) \u0026gt;\u0026gt;\u0026gt; a.shape (3, 5) \u0026gt;\u0026gt;\u0026gt; a.ndim 2 \u0026gt;\u0026gt;\u0026gt; a.dtype.name \u0026#39;int64\u0026#39; \u0026gt;\u0026gt;\u0026gt; a.itemsize 8 \u0026gt;\u0026gt;\u0026gt; a.size 15 \u0026gt;\u0026gt;\u0026gt; type(a) \u0026lt;class \u0026#39;numpy.ndarray\u0026#39;\u0026gt; \u0026gt;\u0026gt;\u0026gt; b = np.array([6, 7, 8]) \u0026gt;\u0026gt;\u0026gt; b array([6, 7, 8]) \u0026gt;\u0026gt;\u0026gt; type(b) \u0026lt;class \u0026#39;numpy.ndarray\u0026#39;\u0026gt; Array creation using array(): 1 2 3 4 \u0026gt;\u0026gt;\u0026gt; import numpy as np \u0026gt;\u0026gt;\u0026gt; a = np.arrary([2, 3, 4]) \u0026gt;\u0026gt;\u0026gt; a array([2, 3, 4]) the type of the array can also be explicitly specified at creation time: 1 \u0026gt;\u0026gt;\u0026gt; c = np.array([[1, 2], [3, 4]], dtype=np.complex128) Often, the elements of an array are originally unknown, but its size is known. Hence, NumPy offers several functions to create arrays with initial placeholder content. These minimize the necessity of growing arrays, an expensive operation.\nthe function zeros() creates an array full of zeros, while ones() ones.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \u0026gt;\u0026gt;\u0026gt; np.zeros((3, 4)) array([[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]]) \u0026gt;\u0026gt;\u0026gt; np.ones((2, 3, 4), dtype=np.int16) array([[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]], [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]], dtype=int16) \u0026gt;\u0026gt;\u0026gt; np.empty((2, 3)) array([[3.73603959e-262, 6.02658058e-154, 6.55490914e-260], # may vary [5.30498948e-313, 3.14673309e-307, 1.00000000e+000]]) a sequence of numbers ($arange(m, n, step)([m,n))$): 1 2 \u0026gt;\u0026gt;\u0026gt; np.arange(10, 30, 5) array([10, 15, 20, 25]) linespace(begin, end, count)$[\\text{begin},\\space \\text{end}]$ 1 2 3 4 5 6 x = np.linspace(0, 2, 10) array( [0. , 0.22222222, 0.44444444, 0.66666667, 0.88888889, 1.11111111, 1.33333333, 1.55555556, 1.77777778, 2. ] ) Printing arrays print(nparray)\nBasic operations Arithmetic operators on arrays apply elementwise. A new array is created and filled with the result.\nelementwise product:\n1 A * B matrix product:\n1 A @ B When operating with arrays of different types, the type of the resulting array corresponds to the more general or precise one (a behavior known as upcasting).\nUniversal functions NumPy provides familiar mathematical functions such as $\\sin,\\space\\cos$, and $\\text{exp}$. In NumPy, these are called \u0026ldquo;universal functions\u0026rdquo;(ufunc). Within NumPy, these functions operate elementwise on an array, producing an array as output.\n1 2 3 4 5 \u0026gt;\u0026gt;\u0026gt; B = np.arange(3) \u0026gt;\u0026gt;\u0026gt; B array([0, 1, 2]) \u0026gt;\u0026gt;\u0026gt; np.exp(B) array([1. , 2.71828183, 7.3890561 ]) Indexing, slicing and iterating One-dimensional arrays can be indexed, sliced and iterated over, much like lists and other Python sequences. 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 \u0026gt;\u0026gt;\u0026gt; a = np.arange(10)**3 \u0026gt;\u0026gt;\u0026gt; a array([ 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]) \u0026gt;\u0026gt;\u0026gt; a[2] 8 \u0026gt;\u0026gt;\u0026gt; a[2:5] array([ 8, 27, 64]) \u0026gt;\u0026gt;\u0026gt; # equivalent to a[0:6:2] = 1000; \u0026gt;\u0026gt;\u0026gt; # from start to position 6, exclusive, set every 2nd element to 1000 \u0026gt;\u0026gt;\u0026gt; a[:6:2] = 1000 \u0026gt;\u0026gt;\u0026gt; a array([1000, 1, 1000, 27, 1000, 125, 216, 343, 512, 729]) \u0026gt;\u0026gt;\u0026gt; a[::-1] # reversed a array([ 729, 512, 343, 216, 125, 1000, 27, 1000, 1, 1000]) \u0026gt;\u0026gt;\u0026gt; for i in a: ... print(i**(1 / 3.)) ... 9.999999999999998 # may vary 1.0 9.999999999999998 3.0 9.999999999999998 4.999999999999999 5.999999999999999 6.999999999999999 7.999999999999999 8.999999999999998 Multidimensional arrays can have one index per axis. Thesse indices are given in a tuple separated by commas: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 \u0026gt;\u0026gt;\u0026gt; def f(x, y): ... return 10 * x + y ... \u0026gt;\u0026gt;\u0026gt; b = np.fromfuction(f, (5, 4), dtype=np.int_) \u0026gt;\u0026gt;\u0026gt; b array([[ 0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23], [30, 31, 32, 33], [40, 41, 42, 43]]) \u0026gt;\u0026gt;\u0026gt; b[2, 3] 23 \u0026gt;\u0026gt;\u0026gt; b[0:5, 1] # each row in the second column of b array([ 1, 11, 21, 31, 41]) \u0026gt;\u0026gt;\u0026gt; b[:, 1] # equivalent to the previous example array([ 1, 11, 21, 31, 41]) \u0026gt;\u0026gt;\u0026gt; b[1:3, :] # each column in the second and third row of b array([[10, 11, 12, 13], [20, 21, 22, 23]]) \u0026hellip; (skip) (more ways to get a slice)\nShape manipulation Changing the shape of an array An array has a shape given by the number o felements along each axis:\n1 2 3 4 5 6 7 \u0026gt;\u0026gt;\u0026gt; a = np.floor(10 * rg.random((3, 4))) \u0026gt;\u0026gt;\u0026gt; a array([[3., 7., 3., 4.], [1., 4., 2., 2.], [7., 2., 4., 9.]]) \u0026gt;\u0026gt;\u0026gt; a.shape (3, 4) The shape of an array can be changed with various commands. Note that the following three commands all return a modified array, but do not change the original array:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 \u0026gt;\u0026gt;\u0026gt; a.ravel() # returns the flattened array array([3., 7., 3., 4., 1., 4., 2., 2., 7., 2., 4., 9.]) \u0026gt;\u0026gt;\u0026gt; a.reshape(6, 2) # returns the array with a modified shape array([[3., 7.], [3., 4.], [1., 4.], [2., 2.], [7., 2.], [4., 9.]]) \u0026gt;\u0026gt;\u0026gt; a.T # returns the array, transposed array([[3., 1., 7.], [7., 4., 2.], [3., 2., 4.], [4., 2., 9.]]) By the way: of np.random init the seed:\n1 \u0026gt;\u0026gt;\u0026gt; np.random.seed(int(hashlib.sha256(\u0026#34;Aminiam\u0026#34;.encode()).hexdigest(), 16) % (2**32)) print:\n1 2 3 4 \u0026gt;\u0026gt;\u0026gt; print(np.random.random((3,3))) [[0.59908781 0.55341069 0.73192068] [0.61572755 0.97373193 0.27759232] [0.53090874 0.57221723 0.63055102]] By the way: of random 1 2 3 4 \u0026gt;\u0026gt;\u0026gt; import random as rd \u0026gt;\u0026gt;\u0026gt; rd.seed(10086) \u0026gt;\u0026gt;\u0026gt; rd.random() 0.043562757723543566 View or shallow copy View() method creates a new array object that looks at the same data.\n1 2 3 4 5 6 7 \u0026gt;\u0026gt;\u0026gt; c = a.view() \u0026gt;\u0026gt;\u0026gt; c is a False \u0026gt;\u0026gt;\u0026gt; c.base is a True \u0026gt;\u0026gt;\u0026gt; c.flags.owndata False Slicing an array returns a view of it.\n1 2 \u0026gt;\u0026gt;\u0026gt; s = a[:, 1:3] s[:] = 10 # s[:]is a view of `s`. Note the difference between `s=10` and `s[:]=10` Deep copy The copy() method makes a complete copy f the array and its data.\n1 2 3 \u0026gt;\u0026gt;\u0026gt; d = a.copy() \u0026gt;\u0026gt;\u0026gt; d is a False Sometimes copy() should be called after slicing if the original array is not required anymore. For example, suppose a is a huge intermediate result and the final result b only contains a small fraction of a, a deep copy should be made when constructing b with slicing.\nLess basic Broadcasting rules Broadcasting allows universal functions to deal in a meaningful way with inputs that do not have exactly the same shape.\nThe first rule of broadcasting is that if all input arrays do not have the same number of dimensions, a \u0026ldquo;1\u0026rdquo; will be repeatedly prepended to the shapes of the smaller arrays until all the arrays have the same number of dimensions.\nThe second rule of broadcasting ensures that arrays with a size of 1 along a particular dimension act as if the had the size of the array with the largest shape along that dimension. The value of the array element is assumed to be the same along that dimension for the \u0026ldquo;broadcast\u0026rdquo; array.\nAfter application of the broadcasting rules, the sizes of all arrays must match.\nAdvanced indexing and index tricks Indexing with arrays of indices ","date":"2026-08-31T19:27:00+08:00","permalink":"/p/numpy-notes/","title":"Note for Numpy"},{"content":"本體語法 自定義輸出行爲：\n方法一：\n1 2 import sys sys.stdout.write(\u0026#34;Hello!\\n\u0026#34;) 方法二：\n1 2 def printf(string : str): print(string, end=\u0026#39;\u0026#39;, sep=\u0026#39;\u0026#39;) 自定義讀入行爲：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 \u0026gt;\u0026gt;\u0026gt; import sys \u0026gt;\u0026gt;\u0026gt; line = sys.stdin.read() Hello World! \u0026gt;\u0026gt;\u0026gt; # line = \u0026#34;Hello World!\\n\u0026#34; \u0026gt;\u0026gt;\u0026gt; line = sys.stdin.readline().rstrip(\u0026#39;\\n\u0026#39;) Hello World! \u0026gt;\u0026gt;\u0026gt; # line = \u0026#34;Hello World!\u0026#34; \u0026gt;\u0026gt;\u0026gt; char = sys.stdin.read(1) Hello World! \u0026gt;\u0026gt;\u0026gt; # char = \u0026#39;H\u0026#39; \u0026gt;\u0026gt;\u0026gt; all_content = sys.stdin.read() \u0026gt;\u0026gt;\u0026gt; # read to EOF (suitable for pipe) \u0026gt;\u0026gt;\u0026gt; for line in sys.stdin: ... print(repr(line)) # to print \u0026#39;\\n\u0026#39; explicitly cuz `line` has \u0026#39;\\n\u0026#39; surfix \u0026lt;str\u0026gt;.title() 以首字母大寫返回每一個單詞，\u0026lt;str\u0026gt;.upper()大寫，\u0026lt;str\u0026gt;.lower()小寫\n+拼接str\n\\t製表符\n\u0026lt;str\u0026gt;.lstrip(), \u0026lt;str\u0026gt;.rstrip(), \u0026lt;str\u0026gt;.strip()，返回str左右兩端空格，不修改，修改另存儲爲\u0026lt;str\u0026gt; = \u0026lt;str\u0026gt;.strip()\n\u0026quot;\u0026quot;字符串可以換行，''字符串不可換行\nprint(a, b)的默認行爲是a,\u0026lt;space\u0026gt;b\\n\nstr拼接需強轉\u0026lt;strA\u0026gt; + str(10086) + \u0026lt;strB\u0026gt;\n3 / 2 = 1, 3.0 / 2.0 = 1.5, 3.0 / 2 = 1.5, 3 / 2.0 = 1.5\n列表[elementA, elementB, ...]\n\u0026lt;list\u0026gt;.append()尾插，\u0026lt;list\u0026gt;.insert(N)索引處插入，索引及右右移一位，\u0026lt;list\u0026gt;.del(N)刪除索引，\u0026lt;list\u0026gt;.pop()彈出隊尾，\u0026lt;list\u0026gt;.pop(N)彈出索引\n\u0026lt;list\u0026gt;.remove()根據值刪除元素\n\u0026lt;list\u0026gt;.sort()永久排序，\u0026lt;list\u0026gt;.sort(reverse=True)逆序，\u0026lt;list\u0026gt;.sorted()返回臨時排序\n\u0026lt;list\u0026gt;.reverse()永久翻轉\n\u0026lt;list\u0026gt;.len()長度\nfor element in list:按引用訪問\nrange(a,b,c)：$[a,b)(step = c)$\n切片\u0026lt;list\u0026gt;[a:b]：$[a,b)$\n\u0026lt;listA\u0026gt; = \u0026lt;listB\u0026gt;複製引用\nShallow copy:\n1 2 3 4 5 6 import copy a = [1, 2, [3, 4]] b = a.copy() b = a[:] b = list(a) b = copy.copy(a) 頂層元素修改不影響，修改嵌套的可變對象（比如a[2].append(5)）b也會改變\nDeep copy:\n1 2 a = [1, 2, [3, 4]] b = copy.deepcopy(a) tuple：(elementA, elementB)，不可以修改元組的元素，但是可以重新定義整個元組（修改元組變量）\nnot \u0026gt; and \u0026gt; or, ==, !=, \u0026gt;/\u0026lt;(=)\n位運算：\n運算 名稱 \u0026amp; 按位與 | 按位或 ~ 按位非 ^ 按位抑或 \u0026lt;\u0026lt; / \u0026gt;\u0026gt; 左右位移 位運算 \u0026gt; 比較運算 \u0026gt; 邏輯運算\n檢查元素是否在list中：element (not) in \u0026lt;list, array, tuple\u0026gt; ，返回True / False\nif-elif-else\n檢查列表是否爲空：if \u0026lt;list\u0026gt;，不爲空True，空False（It says this is Pytholic?）\n字典：{key : value, key : value, ...}，按key訪問\u0026lt;dict\u0026gt;[key]，添加元素\u0026lt;dict.[new_key] = element，創建空字典dict = {}，刪除元素del \u0026lt;dict\u0026gt;[key]\n遍歷字典：for key, value in dict\n遍歷字典所有鍵：for key in dict.keys()\n遍歷字典所有值：for value in dict.values()\n默認值同cpp全部放右側\n沒有函數重載\n函數傳遞整數、浮點、字符串、元組傳遞地址但是修改時會另外創建新對象，列表、字典、集合傳遞地址，修改時會直接修改元素\n禁止函數修改列表：將列表的副本傳遞給函數：func(\u0026lt;list\u0026gt;[:])（潛copy）\n傳遞任意數量的實參：\n1 2 3 4 5 6 7 \u0026gt;\u0026gt;\u0026gt; def func(*args): ... print(args) ... \u0026gt;\u0026gt;\u0026gt; func(\u0026#39;A\u0026#39;) (\u0026#39;A\u0026#39;,) \u0026gt;\u0026gt;\u0026gt; func(\u0026#39;B\u0026#39;, \u0026#39;C\u0026#39;, \u0026#39;D\u0026#39;) (\u0026#39;B\u0026#39;, \u0026#39;C\u0026#39;, \u0026#39;D\u0026#39;) 傳遞任意數量的關鍵字實參：\n1 2 3 4 5 \u0026gt;\u0026gt;\u0026gt; def func(**args): ... profile = {} ... for key, value in args: ... dict[key] = value ... return dict 將函數存儲在模塊中：\n1 2 3 4 5 6 7 8 9 10 # ./a.py def func_1(): return # or `return None` # ./package/b.py def func_2(): return # ./package/__init__.py # ./main.py import a import package.b 子目錄相對導入：\n1 2 3 4 5 6 7 8 9 - PROJETC - main.py - c.py - package |- a.py |- b.py # b.py import .a import ..c from module import function\nfrom module import function as func\n類：\n1 2 3 4 5 6 7 class cls(): \u0026#34;\u0026#34;\u0026#34;description\u0026#34;\u0026#34;\u0026#34; def __init__(a, b): self.a = a self.b = b def func(self): return 繼承：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class A(): def __init__(a, b): self.a = a self.b = b def func(): print(\u0026#34;A\u0026#34;) return class B(): def __init__(a, b, c): super().__init__(a, b) self.c = c def func(): # super().func() is overrided super().func() print(\u0026#34;B\u0026#34;) return 讀取文件：\n1 2 # hello.txt Hello World! 1 2 3 with open(\u0026#39;hello.txt\u0026#39;) as file_object: contents = file_object.read() print(contents) 1 Hello World! 關鍵字with在不需要訪問文件後將其關閉，也可使用open(), close()来控制儘管這是不推薦的\n文件訪問的路徑爲當前相對路徑\n逐行讀取：\n1 2 3 with open(\u0026#39;hello.txt\u0026#39;) as file_obj: for line in file_obj: print(line) 這樣會多出空行，因爲line的結尾有換行符，寫爲：print(line.rstrip())即可（？）\n創建一個包含文件各行內容的列表（只能在with內訪問文件對象，那麼在with外需要訪問的時候就需要用列表拷貝一份\n1 2 3 4 with open(\u0026#39;Hello.txt\u0026#39;) as f: lines = f.readlines() for line in lines: print(line.rstrip()) 寫入文件：\n1 2 with open(\u0026#34;Bye.txt\u0026#34;, \u0026#39;w\u0026#39;) as f: f.write(\u0026#34;Bye World!\u0026#34;) 讀取：'r'，寫入：'w'，追加：'a'\n如果寫入的文件不存在，Python 將自動創建它\nwrite()默認不寫入\\n\n異常（神了，我cpp都沒學異常）\n存儲數據（使用json）（JavaScript Object Notation）\n使用json.dump(), json.load()：\n1 2 3 4 import json numbers = [1, 0, 0, 8, 6] with open(\u0026#39;data.json\u0026#39;, \u0026#39;w\u0026#39;) as f: json.dump(numbers, f) 1 2 3 4 import json with open(\u0026#39;data.json\u0026#39;) as f: numbers = json.load(f) print(numbers) 列表推导式：\n1 list[expr for var in iteratable_obj] 1 a = [x for x in range(5)] 等价于：\n1 2 3 a = [] for x in range(5): a.append(x) 约定：for _ in range iteratable_object表示不关心循环变量\n1 [0] * 3 == [0] + [0] + [0] == [0, 0, 0] 列表相加表示拼接列表\n因此创建一个$m\\times n$的数组只需要：\n1 a = [[0] * n for _ in range(m)] 或者这样定义：\n1 2 3 def matrix(m, n, val=0): return [val * n for _ in range(m)] a = matrix(3, 4, 1) 判断值是否在dict中：\n1 2 if value in dict.values(): pass 標準庫 math 1 2 3 4 5 6 7 8 9 10 from math import * sqrt(16) == 4.0 floor(3.3) == 3 cell(3.3) == 4 gcd(12, 18) == 6 lcm(4, 6) == 12 log(8, 2) == 3.0 log2(8) == 3.0 pi == 3.1415926... inf == ∞ 还有一些常见函数直接隶属Python：\n1 2 3 4 5 6 abs(-3) == 3 pow(2, 3) == 8.0 round(3.14159, 2) = 3.14 min() max() sum([1, 2, 3]) random 1 2 3 4 5 6 7 8 from random import * random() # float in [0, 1) randint(1, 10) # random integer in [1, 10] # note that it\u0026#39;s right closed randrange(10) # 0 ~ 9 # note that it\u0026#39;s right open choice([0, 1, 2]) # choose from randomly shuffle(a) # shuffle randomly sample(a, 3) # get a random sample of 3 seed(10086) # set seed time 1 2 3 from time import * t = time() # get UNIX timestamp print(t) time a programme\n1 2 3 4 5 start = time.perf_counter() for i in range(1000000): pass end = time.perf_counter() print(end - start) # seconds sleep：\n1 sleep(1) # sleep for 1s datetime 1 2 3 4 5 6 7 import datetime now = datetime.now() print(now) print(now.year) print(now.month) print(now.day) print(now.hour) 1 2 3 4 5 2026-09-02 08:43:21.310003 2026 9 2 8 同样还有：now.minute, now.second\n创建时间：\n1 dt = datetime.datetime(2026, 9, 2, 22, 30) 时间差：\n1 2 now = datetime.datetime.now() tomorrow = now + timedelta(days=1) 格式化：\n1 now.strftime(\u0026#34;%Y-%m-%d %H:%M:%S\u0026#34;) 解析字符串：\n1 2 3 4 datetime.strptime( \u0026#34;2026-09-02 08:50:29\u0026#34;, \u0026#34;%Y-%m-%d %H-%M-%S\u0026#34; ) collections deque 1 2 3 4 5 6 from collections import deque q = deque([1, 2, 3]) q.append(4) q.appendleft(0) q.pop() q.popleft() Counter 统计元素出现次数：\n1 2 3 4 from collections import Counter cnt = Counter(\u0026#34;hello\u0026#34;) print(cnt) print(cnt[\u0026#34;l\u0026#34;]) defaultdict 1 2 3 4 5 from collections import defaultdict d = defaultdict(list) d[\u0026#34;a\u0026#34;].append(1) d[\u0026#34;a\u0026#34;].append(2) d[\u0026#34;b\u0026#34;].append(3) 普通dict访问不存在的key会报错，defaultdict可以自动创建默认值\n比如计数：\n1 2 3 cnt = defaultdict(int) for x in [1, 2, 2, 3]: cnt[x] += 1 itertools 迭代器工具\n排列：\n1 2 3 \u0026gt;\u0026gt;\u0026gt; from itertools import permutations \u0026gt;\u0026gt;\u0026gt; list(permutations([1, 2, 3])) [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)] 组合：\n1 2 3 \u0026gt;\u0026gt;\u0026gt; from itertools import combinations \u0026gt;\u0026gt;\u0026gt; list(combinations([1, 2, 3, 4], 2)) [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] 笛卡儿积：\n1 2 3 \u0026gt;\u0026gt;\u0026gt; from itertools import product \u0026gt;\u0026gt;\u0026gt; list(product([0, 1], repeat=3)) [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)] 其他：\n1 2 3 4 itertools.chain(...) itertools.accumulate(...) itertools.repeat(...) itertools.count(...) heapq 堆（默认小根堆）\nbisect 在有序序列中二分\nfunctools 函数工具，最常见是缓存：\n1 2 3 4 5 6 7 from functools import cache @cache def f(n): if n \u0026lt;= 1: return n return f(n - 1) + f(n - 2) @cache会自动缓存函数结果\noperator 操作函数：\n1 2 from operator import add add(2, 3) 常用于排序：\n1 2 3 4 5 6 7 from operator import itemgetter a = [ (\u0026#34;A\u0026#34;, 20), (\u0026#34;B\u0026#34;, 18), (\u0026#34;C\u0026#34;, 22) ] a.sort(key=temgetter(1)) string 字符串常量\n1 2 3 4 import string string.ascii_lowercase # abcdefghijklmnopqrstuvwxyz string.ascii_uppercase # ABCDEFGHIJKLMNOPQRSTUVWXYZ string.digits # 0123456789 re 正则表达式\nos 操作系统\n获取当前目录：\n1 2 import os os.getcwd() 查看文件：\n1 os.listdir(\u0026#34;.\u0026#34;) 创建目录：\n1 os.mkdir(\u0026#34;hello\u0026#34;) 环境变量：\n1 os.environ[\u0026#34;PATH\u0026#34;] 尽管现代 Python 更推荐用pathlib处理路径\npathlib 文件路径\n1 2 3 4 5 6 7 8 9 10 \u0026gt;\u0026gt;\u0026gt; from pathlib import Path \u0026gt;\u0026gt;\u0026gt; p = Path(\u0026#34;data/test.txt\u0026#34;) \u0026gt;\u0026gt;\u0026gt; print(p.exists()) True \u0026gt;\u0026gt;\u0026gt; print(p.name) test.txt \u0026gt;\u0026gt;\u0026gt; print(p.stem) test \u0026gt;\u0026gt;\u0026gt; print(p.suffix) .txt 创建路径：\n1 p = Path(\u0026#34;data\u0026#34;) / \u0026#34;test.txt\u0026#34; 遍历文件：\n1 2 for p in Path(\u0026#34;.\u0026#34;).glob(\u0026#34;*.py\u0026#34;): print(p) 递归查找：\n1 Path(\u0026#34;.\u0026#34;).rglob(\u0026#34;*.py\u0026#34;) sys Python 运行环境\n命令行参数：\n1 2 import sys print(sys.argv) 标准输入：\n1 input = sys.stdin.readline 标准输出：\n1 print(\u0026#34;Hello\u0026#34;, file=sys.stdout) 退出程序：\n1 sys.exit() 运行外部程序：\n1 2 import subprocess subprocess.run([\u0026#34;git\u0026#34;, \u0026#34;status\u0026#34;]) copy 浅复制：copy.copy()，深复制：copy.deepcopy()\n","date":"2026-08-31T19:27:00+08:00","permalink":"/p/python-notes/","title":"Note for Python"},{"content":"原題 AtCoder 原題：F - Centroid of a Slice\n多边形重心坐标 對有$N$個頂點的平面多邊形的每個頂點有$(x_i,y_i)$有：\n$$ G_x = \\frac{\\sum_i{(x_i+x_{i+1})S_i}}{3\\sum_i{S_i}} \\newline G_y = \\frac{\\sum_i{(y_i+y_{i+1})S_i}}{3\\sum_i{S_i}} $$ 其中：\n$$ S_i = \\frac{1}{2}(x_iy_{i+1}-x_{i+1}y_i) \\newline x_{N+1} = x_1 \\newline y_{N+1} = y_1 $$ 注意事項 使用前綴和時，記得閉合最後一條邊。\nAC代碼 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 #include \u0026lt;cstdio\u0026gt; const int SIZE = (1e6 + 10); typedef long double ld; int main() { //read int N, Q; scanf(\u0026#34;%d%d\u0026#34;, \u0026amp;N, \u0026amp;Q); int x[SIZE] = {0}, y[SIZE] = {0}; ld ax[SIZE] = {0}, ay[SIZE] = {0}, b[SIZE] = {0}; for (int i = 1; i \u0026lt;= N; i++) scanf(\u0026#34;%d%d\u0026#34;, \u0026amp;x[i], \u0026amp;y[i]); x[N + 1] = x[1]; y[N + 1] = y[1]; for (int i = 1; i \u0026lt;= N; i++) { ax[i] = ax[i - 1] + ((ld)x[i] + (ld)x[i + 1]) * ((ld)x[i] * (ld)y[i + 1] - (ld)x[i + 1] * (ld)y[i]); ay[i] = ay[i - 1] + ((ld)y[i] + (ld)y[i + 1]) * ((ld)x[i] * (ld)y[i + 1] - (ld)x[i + 1] * (ld)y[i]); b[i] = b[i - 1] + (ld)x[i] * (ld)y[i + 1] - (ld)x[i + 1] * (ld)y[i]; } //output for (int i = 0; i \u0026lt; Q; i++) { int u, v; scanf(\u0026#34;%d%d\u0026#34;, \u0026amp;u, \u0026amp;v); ld ans_x, ans_y, sb, sax, say; if (u \u0026lt; v) { sb = b[v - 1] - b[u - 1]; sax = ax[v - 1] - ax[u - 1]; say = ay[v - 1] - ay[u - 1]; } else { sb = b[N] - b[u - 1] + b[v - 1]; sax = ax[N] - ax[u - 1] + ax[v - 1]; say = ay[N] - ay[u - 1] + ay[v - 1]; } //close ld c = (ld)x[v] * (ld)y[u] - (ld)x[u] * (ld)y[v]; sb += c; sax += ((ld)x[v] + (ld)x[u]) * c; say += ((ld)y[v] + (ld)y[u]) * c; ans_x = sax / sb / 3.0L; ans_y = say / sb / 3.0L; printf(\u0026#34;%.12Lf %.12Lf\\n\u0026#34;, ans_x, ans_y); } return 0; } ","date":"2026-08-25T23:30:24+08:00","permalink":"/p/%E5%A4%9A%E9%82%8A%E5%BD%A2%E9%87%8D%E5%BF%83/","title":"多邊形重心"},{"content":"烹飪心得 老的韭菜不能收湯太多或者加水太少，否則容易老。\n粉絲用水泡過之後，和佐料一起燒滾一趟即可。\n茄子水不能放多（一盤量，加一小口水即可），否則容易爛掉。\n空心菜油要多放一點，開大火爆炒一小會兒即可。\n煸大蒜前倒大蒜的時候建議火開小一點，否則容易炸。\n準備配菜的時候湯鍋開了小火，燒滾的時候記得開大火。\n","date":"2026-08-24T18:30:39+08:00","image":"/p/%E7%83%B9%E9%A3%AA%E5%BF%83%E5%BE%97/cooking.jpg","permalink":"/p/%E7%83%B9%E9%A3%AA%E5%BF%83%E5%BE%97/","title":"烹飪心得"},{"content":"方案一：vector 鄰接表 使用vector\u0026lt;int\u0026gt; n;，n[i]儲存了第$i$個節點的所有鄰居。\nadd(a, b) (vector) 1 2 a.push_back(b); b.push_back(a); DFS (vector) 遞歸實現，首先定義bool st[SIZE] = {false};來記錄節點是否被訪問過。\n1 2 3 4 5 6 7 8 void dfs(head) { st[head] = true; //標記當前節點 run(head); //執行操作 for (auto v : n[head]) if (!st[v]) dfs(v); } BFS (vector) 使用隊列queue\u0026lt;int\u0026gt; q;\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 st[head] = true; //先記錄head已經被訪問 q.push(head); //將head插入隊尾 while (!q.empty()) //開始循環 { int f = q.front(); q.pop(); run(f); for (auto v : n[f]) if (!st[v]) { st[v] = true; q.push(v); } } 方案二：鏈式前向星 定義：\n1 2 3 4 int h[N]; int e[2 * N]; int ne[2 * N]; int id = 0; add(a, b) (static) 1 2 3 4 5 6 7 8 id++; //分配內存 e[id] = b; //儲存值 ne[id] = h[a]; //頭插 h[a] = id; //頭插 id++ e[id] = a; ne[id] = h[b]; h[b] = id; DFS (static) 遞歸實現：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 void dfs(head) { st[head] = true; run(head); for (int i = n[head]; i; i = ne[i]) { int v = e[i]; if (!st[v]) { st[v] = true; dfs(v); } } } BFS (static) 使用隊列queue\u0026lt;int\u0026gt; q;\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 st[head] = true; q.push_front(head); while (!q.empty()) { int f = q.front(); q.pop(); run(f); //在此處run for (int i = n[f]; i; i = ne[i]) { int v = e[i]; if (!st[v]) { st[v] = true; q.push(v); //這裏是push不是run } } } ","date":"2026-08-22T16:18:53+08:00","permalink":"/p/tree%E6%9D%BF%E5%AD%90/","title":"tree板子"},{"content":"檢查左端點 1 2 3 4 5 6 7 int l = 1, r = n; while (l \u0026lt; r) { int mid = (l + r) / 2; if(check(mid)) r = mid; else l = mid + 1; } 檢查右端點 1 2 3 4 5 6 7 int l = 1, r = n; while (l \u0026lt; r) { int mid = (l + r + 1) / 2; if(check(mid)) l = mid; else r = mid - 1; } ","date":"2026-08-22T16:15:06+08:00","permalink":"/p/%E4%BA%8C%E5%88%86%E6%9D%BF%E5%AD%90/","title":"二分板子"},{"content":"文言文議論文論證邏輯思考 文言文議論文的邏輯無非以下兩種：\n×××信仁也，仁而不王者，未之有也。\n×××非仁也，非仁而王者，未之有也。\n","date":"2026-08-22T15:31:18+08:00","permalink":"/p/%E6%96%87%E8%A8%80%E8%AB%96%E8%AD%89%E9%82%8F%E8%BC%AF%E6%80%9D%E8%80%83/","title":"文言論證邏輯思考"},{"content":"揚中除了歷史還剩下什麼 此文用以回忆我高中三年的生活。尽管很多叙述有失偏颇，但是所有叙事都来自亲历视角。\n将所有无法言说的欢欣和怅惘都献给自己和所有与我亲历这一切的他者。\n还在上强基的时候，我对张振轩说，从树人会馆到扬中的这条通泗街，我还要用脚步丈量它的长度多少遍。可无论走多少遍，中午也好，雨天也好，在多少个需要忍受的每一天之后，依然走向了它的终章。不论我痛恨也好，眷恋也好，我、所有行走在通泗街上的人也好，或许只有行走的权利——在此时此刻拥有一次行走的权利，不论这是第一次，还是最后一次。\n最后在扬中的那段时间，教师健身房和风雨跑道或许是最后令我无比眷恋的地方。无论是一阵风吹过婆娑作响的梧桐树也好，昏黄的傍晚树人堂前水池边灯光里的石凳也好，一切宁静、美丽的景色最后依然输给了真实的铁杆和哑铃的触感。那是一种怎样的让渡？一切审美力在不停的微小折磨中，屈膝俯首。我并没有否认运动的快乐，在健身房的四十分钟或者一个小时，是琐碎生命里最后能掌握的不曾被侵扰的时光。或许这种让渡不是一种主动的舍弃，而是我不能够再做出其它的选择。毕竟，离开了这里，回头的路上，还有太多事由等着我。\n三年前走进扬中的时候，首先背下来的是“自治自动，体育兼重”“正直向上，热于求知”和“百廿名校”。\n一百二十年，确实是一段很久的历史了。久到学校的名字都变更了多少次，久到校长都在任了多少位，久到一切都不必再继承——因为那是一个抽象的过去，哪里有人能怀古心、师尧舜，不是不想，只是在每一天的消磨里，如此背离了而已。“天变不足畏，祖宗不足法，人言不足恤”又能概括多少你我他她的生存境遇？又或者只是将将也就足一日光阴寸短了了？传承血脉，继往开来的华章里，究竟流淌着多少血脉？\n当我们使用着前人的语汇的时候，只是填充着自己的实践。\n我记得，徐树老师曾在一堂竞赛课上对我们说，某金牌学长认真钻研，反复思考，花了一个月的时间终于弄明白了一道题，以此鼓励我们多加思考。\n原来，想了一个月连个问的人都没有啊……\n我不是为了曲解，我只是感到可悲。\n我上初中的时候就听说扬中物竞最拿得出手，还有一支自己的竞赛教练队伍。机缘巧合进了物竞，结识了照本宣科的人，结识了刚愎自用的人，结识了甩手掌柜的人，但所有的人都不是坏人，我们只是好心却办不了事而已。\n许肇哲保送了，肖老师告诉我这个消息。吃完饭回来的时候，许肇哲坐在我的座位上，看我写的胡话，当时他看“……”这段的时候，在旁边写了一句“这不就是……”，还没等他写完我就在他脑袋上抽了一巴掌，然后我就走了。难得为值得高兴的事哭泣，或许只是因为他只看到了他想看到的。\n许肇哲，你评价了我写的那么多东西，多少是你擅自看的，我让你评价了吗？那天，走在去操场的路上，你跟我说，你写的那个“这是一条河流……”，不就是在说“错过”吗？是，是“错过”，但你只看到了你看到的“错过”。多久之后你还跟我说你还在想你那点破事啊，是，你告诉我这一切荒诞你要去反抗，这一切虚无我已经找到意义，可是我又何曾讨论的是虚无，我又何曾讨论的是意义？\n除了加缪，你还能搬出一点别的东西吗？\n除了荒诞，你还能理解一点其他的生活吗？\n可是除了我所有的诉说，我已经想不出别的什么来讲述我的一切了啊……\n二楼的窗台向西可以眺望青葱的香樟、郁白的玉兰，还有冲刺去食堂买鸡米花和小鸡腿的人。买鸡米花和小鸡腿是多么艰难和曲折，冲刺过去，排队，刷卡，冲刺回来上课，吃完，倒贴一百大卡。后来似乎是家长举报食堂总是售卖油炸食品，还是食堂承包商换了，总之，鸡米花和小鸡腿不再卖了，之后似乎总感觉第二节课下的生活有点寡淡和索然。\n高二春学期开学的时候，和缪余骏去食堂买了新学期第一只小鸡腿，还是那个熟悉的味道。\n高二一年读了人生最多的书；高二认识谢中和徐振；高二开始健身；高二学了繁体字和草书；高二演了课本剧。\n高二是在窗台上凭槛远眺。\n我向上眺望。灯光里，依然能看见几颗明亮的星星。初三那年，我突然抬头，发现了从前从未发现的明亮的星星。我问时予桐那是什么星星，他也不知道。三年后，许肇哲说，那是大火吗？原来是大火吗？七月流火。我不知道它究竟是不是大火。三年前三年后，三个古怪的人，抬头看见了同一颗星星。鲁国万钧王月重，汉天一点客星孤。那是怎样一点孤独的客星，在浩渺的河汉。\n天寒夜长，风气萧索，鸿雁于征，草木黄落。抬头还能看见阵雁南飞，消失在目力所不能及的地方，消失在梧桐树的北面，向西飞去。\n在扬中的一百六十亩地里，要让一个人去体会时暮更替，要让一个人去远征去体会不存在的羁旅和牵绊，要让一个人去爱恋再学会失去。扬中没有赋予我刷题怪兽的无心，没有赋予我牵线木偶的顺从，扬中试图充盈我以情感，却最终没能解答我的问题。院士廊里深邃的凝视没有教会我如何在这一切芜杂里自处，“自治自动”的传统没有教会我如何在失去信仰的时候依然去拯救。问题总是要自己想明白，可是我去问谁呢？上帝，佛陀，众神，我去问谁呢？最后的审判，降以我业火吗？西方的彼岸，降以我食粮吗？\nWe have a basic need to believe in something greater than ourselves. We crave solace in the darkness, a light unto our path. Thanks to you, we\u0026rsquo;ve found meaning amid the Cosmos.\nWho, then, art Thou?\n摘花并不是文明的行为，但我在我的案头放上白色的月季。这是在寻求慰藉吗？或许第二天早上来剪一次花茎，至少证明我还在拥有，我还在热爱。\n这个标题我高二就想好了，只是当时的热爱也好，怨气也好，也都什么都不剩了。\n历史向何处问询？或许没有人做错了任何事。或许扬中还拥有一切，而我已经如此走过，如此虔诚地祈祷：\nDeo Gratias.\n","date":"2026-08-22T15:29:41+08:00","permalink":"/p/%E6%8F%9A%E4%B8%AD%E9%99%A4%E4%BA%86%E6%AD%B7%E5%8F%B2%E9%82%84%E5%89%A9%E4%B8%8B%E4%BB%80%E9%BA%BC/","title":"揚中除了歷史還剩下什麼"},{"content":"設喻 這是一條河流，我騎馬走在河東岸，你騎馬走在河西岸，我們彼此揮手致意。我們設想著一定會有一座木橋溝通著河兩岸，或許就在不遠處。直到前方河道開始變寬，那是一個長滿蘆葉的汀洲，我們逐漸看不見彼此；沙洲上鸚鵡在喧鬧，最後聽不見彼此的馬蹄聲。 ——2025.12.15\n(Waiting for a title) If there should be a beginning to the story And a denouement to the tale, What difference would there be, Borne forward and backward? ——2026.01.18; Revised on 2026.04.16; Rev. II — 2026.05.31\nThe Abyss is the resentment of all the fates that never came to be. (Alice - Homeward, He Who Caught the Wind) ——Excerpted on 2026.03.12\n或許我祇是在尋找一個無關緊要的藉口結束或者逃離。我背棄了一個未曾發生的命運，僅僅因爲我的自私和無私。可是誰又能做出選擇？誰又被允許做出選擇？未曾發生的命運從未被允許發生，這從一開始就已經被構思，祇是在等待被書寫。 ——2026.05.31\n","date":"2026-08-22T15:26:51+08:00","permalink":"/p/%E8%A8%AD%E5%96%BB/","title":"設喻"},{"content":"20260822午休於揚州家中 大學新生入學報道，我的座位是806和807。可能是座位比較多，可以中間隔着一個人空開坐。\n入學儀式開始了，首先舉行升旗儀式。這時，前面的許多排人突然掉轉過頭，衝着我們振臂疾呼，大聲歌唱。\n國歌的聲音異常地響亮，震得耳朵嗡嗡轟鳴。\n我看見旁邊有一個人突然坐了下來，捂住耳朵。\n我也坐了下來，捂住耳朵。\n我右手邊的那個女生看我坐了下來，也坐了下來，意義不明地偷笑。\n國歌結束了，下一首是《我和我的祖國》，卻沒有一個人跟唱。\n另記高三在樹人會館午休時灰白色的夢 TODO\n一直想記下來，一直忘了記下來，直到已經快忘記了當時的感受，那種悲哀和無助。\n","date":"2026-08-22T15:15:27+08:00","permalink":"/p/20260822%E8%AE%B0%E6%A2%A6/","title":"20260822记梦"},{"content":"This post is for testing {PROJECT_SOURCE_DIR}/scripts/new-post.sh.\nAnd {PROJECT_SOURCE_DIR}/scripts/update-date.sh\n","date":"2026-08-19T10:39:37+08:00","permalink":"/p/script-try/","title":"Test `new-post.sh`"},{"content":"Commands Add in {PROJECT_SOURCE_DIR}/.vscode/tasks.json:\n1 2 3 4 5 6 7 8 9 10 { \u0026#34;tasks\u0026#34;: [ { \u0026#34;label\u0026#34;: \u0026#34;Commit \u0026amp; Push\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;shell\u0026#34;, \u0026#34;command\u0026#34;: \u0026#34;git add . \u0026amp;\u0026amp; git commit -m \\\u0026#34;$(date \u0026#39;+%Y-%m-%d %H:%M:%S\u0026#39;)\\\u0026#34; \u0026amp;\u0026amp; git push\u0026#34;, \u0026#34;problemMatcher\u0026#34;: [] } ] } ","date":"2026-08-18T20:31:10+08:00","permalink":"/p/vscode-task-commit-and-push/","title":"VS Code Task: Commit and Push"},{"content":"Commands Update to the latest 1 2 hugo mod get -u github.com/CaiJimmy/hugo-theme-stack/v4 hugo mod tidy Update to specific version 1 hugo mod get github.com/CaiJimmy/hugo-theme-stack/v4@v4.1.0 ","date":"2026-08-18T20:21:46+08:00","permalink":"/p/update-fork/","title":"Update the fork"},{"content":"This article offers a sample of basic Markdown syntax that can be used in Hugo content files, also it shows whether basic HTML elements are decorated with CSS in a Hugo theme.\nHeadings The following HTML \u0026lt;h1\u0026gt;—\u0026lt;h6\u0026gt; elements represent six levels of section headings. \u0026lt;h1\u0026gt; is the highest section level while \u0026lt;h6\u0026gt; is the lowest.\nH1 H2 H3 H4 H5 H6 Paragraph Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.\nItatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.\nBlockquotes The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a footer or cite element, and optionally with in-line changes such as annotations and abbreviations.\nBlockquote without attribution Tiam, ad mint andaepu dandae nostion secatur sequo quae. Note that you can use Markdown syntax within a blockquote.\nBlockquote with attribution Don\u0026rsquo;t communicate by sharing memory, share memory by communicating.\n— Rob Pike1\nTables Tables aren\u0026rsquo;t part of the core Markdown spec, but Hugo supports supports them out-of-the-box.\nName Age Bob 27 Alice 23 Inline Markdown within tables Italics Bold Code italics bold code A B C D E F Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ultricies, sapien non euismod aliquam, dui ligula tincidunt odio, at accumsan nulla sapien eget ex. Proin eleifend dictum ipsum, non euismod ipsum pulvinar et. Vivamus sollicitudin, quam in pulvinar aliquam, metus elit pretium purus Proin sit amet velit nec enim imperdiet vehicula. Ut bibendum vestibulum quam, eu egestas turpis gravida nec Sed scelerisque nec turpis vel viverra. Vivamus vitae pretium sapien Code Blocks Code block with backticks 1 2 3 4 5 6 7 8 9 10 \u0026lt;!doctype html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;utf-8\u0026#34;\u0026gt; \u0026lt;title\u0026gt;Example HTML5 Document\u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;p\u0026gt;Test\u0026lt;/p\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; Code block indented with four spaces \u0026lt;!doctype html\u0026gt;\r\u0026lt;html lang=\u0026quot;en\u0026quot;\u0026gt;\r\u0026lt;head\u0026gt;\r\u0026lt;meta charset=\u0026quot;utf-8\u0026quot;\u0026gt;\r\u0026lt;title\u0026gt;Example HTML5 Document\u0026lt;/title\u0026gt;\r\u0026lt;/head\u0026gt;\r\u0026lt;body\u0026gt;\r\u0026lt;p\u0026gt;Test\u0026lt;/p\u0026gt;\r\u0026lt;/body\u0026gt;\r\u0026lt;/html\u0026gt;\rDiff code block 1 2 3 4 5 [dependencies.bevy] git = \u0026#34;https://github.com/bevyengine/bevy\u0026#34; rev = \u0026#34;11f52b8c72fc3a568e8bb4a4cd1f3eb025ac2e13\u0026#34; - features = [\u0026#34;dynamic\u0026#34;] + features = [\u0026#34;jpeg\u0026#34;, \u0026#34;dynamic\u0026#34;] One line code block 1 \u0026lt;p\u0026gt;A paragraph\u0026lt;/p\u0026gt; List Types Ordered List First item Second item Third item Unordered List List item Another item And another item Nested list Fruit Apple Orange Banana Dairy Milk Cheese Other Elements — abbr, sub, sup, kbd, mark GIF is a bitmap image format.\nH2O\nXn + Yn = Zn\nPress CTRL + ALT + Delete to end the session.\nMost salamanders are nocturnal, and hunt for insects, worms, and other small creatures.\nThe above quote is excerpted from Rob Pike\u0026rsquo;s talk during Gopherfest, November 18, 2015.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-09-07T00:00:00Z","permalink":"/p/markdown-syntax-guide/","title":"Markdown Syntax Guide"},{"content":"For more details, check out the documentation.\nBilibili video Tencent video YouTube video Generic video file Your browser doesn't support HTML5 video. Here is a link to the video instead. GitLab Quote Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n― A famous person, The book they wrote Photo by Codioful on Unsplash\n","date":"2023-08-25T00:00:00Z","image":"/p/shortcodes/cover.jpg","permalink":"/p/shortcodes/","title":"Shortcodes"},{"content":"Stack has built-in support for math typesetting using KaTeX.\nIt\u0026rsquo;s not enabled by default side-wide, but you can enable it for individual posts by adding math: true to the front matter. Or you can enable it side-wide by adding math = true to the params.article section in config.toml.\nInline math This is an inline mathematical expression: $\\varphi = \\dfrac{1+\\sqrt5}{2}= 1.6180339887…$\n1 $\\varphi = \\dfrac{1+\\sqrt5}{2}= 1.6180339887…$ Block math $$\r\\varphi = 1+\\frac{1} {1+\\frac{1} {1+\\frac{1} {1+\\cdots} } } $$ 1 2 3 $$ \\varphi = 1+\\frac{1} {1+\\frac{1} {1+\\frac{1} {1+\\cdots} } } $$ $$\rf(x) = \\int_{-\\infty}^\\infty\\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\\,d\\xi\r$$ 1 2 3 $$ f(x) = \\int_{-\\infty}^\\infty\\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\\,d\\xi $$ ","date":"2023-08-24T00:00:00Z","permalink":"/p/math-typesetting/","title":"Math Typesetting"}]