max i ∈ S x i = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − 1 min i ∈ T x i min i ∈ S x i = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − 1 max i ∈ T x i E ( max i ∈ S x i ) = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − 1 E ( min i ∈ T x i ) E ( min i ∈ S x i ) = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − 1 E ( max i ∈ T x i ) kth max i ∈ S x i = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − k ( ∣ T ∣ − 1 k − 1 ) min i ∈ T x i kth min i ∈ S x i = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − k ( ∣ T ∣ − 1 k − 1 ) max i ∈ T x i E ( kth max i ∈ S x i ) = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − k ( ∣ T ∣ − 1 k − 1 ) E ( min i ∈ T x i ) E ( kth min i ∈ S x i ) = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − k ( ∣ T ∣ − 1 k − 1 ) E ( max i ∈ T x i ) lcm i ∈ S x i = ∏ T ⊆ S ( gcd i ∈ T x i ) ( − 1 ) ∣ T ∣ − 1 \max\limits_{i \in S}x_i = \sum \limits_{T\subseteq S}(-1)^{|T| - 1}\min\limits_{i \in T}x_i \\\min\limits_{i \in S}x_i = \sum \limits_{T\subseteq S}(-1)^{|T| - 1}\max\limits_{i \in T}x_i \\E(\max\limits_{i \in S}x_i) = \sum \limits_{T\subseteq S}(-1)^{|T| - 1}E(\min\limits_{i \in T}x_i) \\E(\min\limits_{i \in S}x_i) = \sum \limits_{T\subseteq S}(-1)^{|T| - 1}E(\max\limits_{i \in T}x_i) \\\text{kth}\max\limits_{i \in S}x_i = \sum\limits_{T \subseteq S}(-1)^{|T|-k}\binom{|T| - 1}{k - 1}\min\limits_{i \in T}x_i\\\text{kth}\min\limits_{i \in S}x_i = \sum\limits_{T \subseteq S}(-1)^{|T|-k}\binom{|T| - 1}{k - 1}\max\limits_{i \in T}x_i\\E(\text{kth}\max\limits_{i \in S}x_i) = \sum\limits_{T \subseteq S}(-1)^{|T|-k}\binom{|T| - 1}{k - 1}E(\min\limits_{i \in T}x_i)\\E(\text{kth}\min\limits_{i \in S}x_i) = \sum\limits_{T \subseteq S}(-1)^{|T|-k}\binom{|T| - 1}{k - 1}E(\max\limits_{i \in T}x_i)\\\underset{i\in S}{\text{lcm}} x_i = \prod\limits_{T \subseteq S}\left(\gcd\limits_{i \in T}x_i\right)^{(-1)^{|T| - 1}} i∈Smaxxi=T⊆S∑(−1)∣T∣−1i∈Tminxii∈Sminxi=T⊆S∑(−1)∣T∣−1i∈TmaxxiE(i∈Smaxxi)=T⊆S∑(−1)∣T∣−1E(i∈Tminxi)E(i∈Sminxi)=T⊆S∑(−1)∣T∣−1E(i∈Tmaxxi)kthi∈Smaxxi=T⊆S∑(−1)∣T∣−k(k−1∣T∣−1)i∈Tminxikthi∈Sminxi=T⊆S∑(−1)∣T∣−k(k−1∣T∣−1)i∈TmaxxiE(kthi∈Smaxxi)=T⊆S∑(−1)∣T∣−k(k−1∣T∣−1)E(i∈Tminxi)E(kthi∈Sminxi)=T⊆S∑(−1)∣T∣−k(k−1∣T∣−1)E(i∈Tmaxxi)i∈Slcmxi=T⊆S∏(i∈Tgcdxi)(−1)∣T∣−1
证明 显然末态(全 0 局面)满足先手必败条件,我们只需证明对于任意 ⨁ i = 1 n a i ≠ 0 \bigoplus\limits_{i = 1}^{n}a_i \not= 0 i=1⨁nai=0 的局面,一定存在一种操作使其能转变为 ⨁ i = 1 n a i = 0 \bigoplus \limits_{i = 1}^{n}a_i = 0 i=1⨁nai=0 的局面。
设此时 ⨁ i = 1 n a i = k ≠ 0 \bigoplus \limits_{i = 1}^{n}a_i = k \not= 0 i=1⨁nai=k=0, k k k 在二进制下最高位的 1 在第 x x x 位,则一定有奇数个 a i a_i ai 在二进制下第 x x x 位为 1。找到其中一个 a i a_i ai,则 a i ⊕ k < a i a_i \oplus k < a_i ai⊕k<ai, 取 a i − ( a i ⊕ k ) a_i - (a_i \oplus k) ai−(ai⊕k) 个石子,则局面转变为 ⨁ i = 1 n a i = 0 \bigoplus \limits_{i = 1}^{n} a_i = 0 i=1⨁nai=0。
证明 先手必败的玩家在 lowbit ( a i ) \text{lowbit}(a_i) lowbit(ai) 最小的石子堆中取走恰好一个,则先手必胜的玩家也必须在另一堆 lowbit ( a i ) \text{lowbit}(a_i) lowbit(ai) 最小的石子堆中取走恰好一个。
证明 显然末态(0)满足先手必败条件,对于任意 ( m + 1 ) ∤ n (m + 1)\not| n (m+1)∣n 的局面,先手取 n n n 模 m + 1 m + 1 m+1 的余数个石子,一定能使其转变为 ( m + 1 ) ∣ n (m + 1)|n (m+1)∣n 的局面。
证明 待补充。
给定一堆石子,石子总个数为 n n n,两名玩家轮流行动:
取走最后一个石子者获胜。
结论 两人均采用最优策略,若 n n n 为 Fibonacci \text{Fibonacci} Fibonacci 数则先手必败,否则先手必胜。
证明 待补充。
证明 若最大匹配一定包含起始点,则先手始终可以沿着匹配边移动,后手不可能选到非匹配点。若后手选到一个非匹配点 P n P_n Pn,设路径为 P 1 → P 2 → ⋯ → P n ( n 为奇数 ) P_1 \to P_2 \to \dots \to P_n(n为奇数) P1→P2→⋯→Pn(n为奇数),则现有匹配为 { P 1 − P 2 , … , P n − 2 − P n − 1 } \{P_1-P_2,\dots, P_{n-2}-P_{n-1}\} {P1−P2,…,Pn−2−Pn−1},则可得到另一个最大匹配 { P 2 − P 3 , … , P n − 1 − P n } \{P_2-P_3, \dots, P_{n - 1}-P_n\} {P2−P3,…,Pn−1−Pn},与最大匹配一定包含起始点矛盾。
若最大匹配不一定包含起始点,取其中一个不包含起始点的最大匹配 M M M,先手每次移动一定会移动到某个匹配点上,否则图中存在增广路,与最大匹配矛盾,后手只需沿匹配边移动即可。
inline bool Gauss()
{
for (int i = 1; i <= n; ++i)
{
int l = i;
for (int j = i + 1; j <= n; ++j)
if (fabs(f[l][i]) < fabs(f[j][i]))
l = j;
if (l != i)
for (int j = 1; j <= n + 1; ++j)
std::swap(f[l][j], f[i][j]);
if (fabs(f[i][i]) <= eps)
return false;
ld tmp = f[i][i];
for (int j = 1; j <= n + 1; ++j)
f[i][j] /= tmp;
for (int j = 1; j <= n; ++j)
if (j != i)
{
ld tmp = f[j][i];
for (int k = i; k <= n + 1; ++k)
f[j][k] -= f[i][k] * tmp;
}
}
return true;
}
bitset
优化。bitset<N> f[N];
inline int Guass() //返回自由元个数
{
// n 为未知量个数,m 为方程数
int ans = 0;
for (int i = 1; i <= n; ++i)
{
int pos = 0;
for (int j = 1; j <= m; ++j)
if (!vis[j] && f[j][i])
{
pos = j;
break;
}
if (pos)
{
if (pos != i)
swap(f[pos], f[i]);
vis[i] = true;
for (int j = 1; j <= m; ++j)
if (!vis[j] && f[j][i]) f[j] ^= f[i];
}
else
++ans; //统计自由元个数
}
for (int i = 1; i <= m; ++i)
{
bool flag = false;
for (int j = 1; j <= n; ++j)
if (f[i][j])
{
flag = true;
break;
}
if (!flag && f[i][n + 1]) //无解情况
return -1;
}
return ans;
}
inline int Det()
{
int res = 1, opt = 0;
for (int i = 1; i <= n; ++i)
{
for (int j = i + 1; j <= n; ++j)
{
while (f[i][i])
{
int tmp = f[j][i] / f[i][i];
for (int k = i; k <= n; ++k)
dec(f[j][k], 1ll * tmp * f[i][k] % mod);
std::swap(f[i], f[j]);
opt ^= 1;
}
std::swap(f[i], f[j]);
opt ^= 1;
}
res = 1ll * res * f[i][i] % mod;
if (!res)
return 0;
}
return opt ? mod - res : res;
}
flag
)。bitset
进行压位优化。struct bigint
{
bitset<N> x;
inline void Clear() {x.reset();}
inline void scan(char *s, int n)
{
x.reset();
std::reverse(s, s + n);
for (int i = 0; i < n; ++i)
if (s[i] == '1')
x[N - 1 - i] = 1;
}
inline bool operator < (const bigint &a) const
{
int p = (x ^ a.x)._Find_first();
if (p == N)
return false;
return !x[p];
}
inline bool operator <= (const bigint &a) const
{
int p = (x ^ a.x)._Find_first();
return p == N || !x[p];
}
}
reBuild
操作,具体来说,从低位到高位,尽量用低位的元素消去高位元素上的 1,只保留线性基中非 0 的元素。reBuild
操作,只保留线性基中非 0 的元素。const int L = 60;
ll cur[L + 1];
int cm;
struct lib
{
ll g[L + 1];
bool flag0;
inline void Clear()
{
flag0 = false;
for (int i = 0; i <= L; ++i)
g[i] = 0;
}
inline bool Insert(ll v)
{
for (int i = L; i >= 0; --i)
if (v >> i & 1)
{
if (g[i])
v ^= g[i];
else
{
g[i] = v;
return true;
}
}
flag0 = true;
return false;
}
inline int queryCnt()
{
int cnt = 0;
for (int i = 0; i <= L; ++i)
cnt += g[i] > 0;
return cnt;
}
inline ll queryMax(ll res = 0)
{
for (int i = L; i >= 0; --i)
if ((res ^ g[i]) > res)
res ^= g[i];
return res;
}
inline ll queryMin(ll res = -1)
{ // res = -1 时表示询问线性基内子集异或和的最小值
if (res == -1)
{
if (flag0)
return 0;
for (int i = 0; i <= L; ++i)
if (g[i])
return g[i];
}
else
{
for (int i = L; i >= 0; --i)
if (res >> i & 1)
res ^= g[i];
return res;
}
}
inline void reBuild()
{ // 使用 queryKth() 之前记得调用
cm = 0;
for (int i = 0; i <= L; ++i)
if (g[i])
{
for (int j = 0; j < i; ++j)
if (g[i] >> j & 1)
g[i] ^= g[j];
cur[cm++] = g[i];
}
}
inline ll queryKth(ll k)
{
if (flag0)
--k;
if (!k)
return 0;
if (k >= (1ll << cm))
return -1;
ll res = 0;
for (int i = 0; i < cm; ++i)
if (k >> i & 1)
res ^= cur[i];
return res;
}
inline ll queryRank(ll r)
{
ll res = 0, cnt = 1;
for (int i = cm - 1; i >= 0; --i)
{
ll temp = res ^ cur[i];
if (temp <= r)
{
res = temp;
cnt += 1ll << i;
}
}
return cnt;
}
friend inline lib operator | (const lib &a, const lib &b)
{
lib c = a;
for (int i = L; i >= 0; --i)
if (b.g[i])
c.Insert(b.g[i]);
c.flag0 |= b.flag0;
return c;
}
friend inline lib operator & (const lib &a, const lib &b)
{
lib c, d, res;
c.flag0 = a.flag0 && b.flag0;
for (int i = L; i >= 0; --i)
{
res.g[i] = a.g[i];
d.g[i] = 1ll << i;
}
for (int i = L; i >= 0; --i)
if (b.g[i])
{
ll v = b.g[i], k = 0;
bool flag = true;
for (int j = L; j >= 0; --j)
if (v >> j & 1)
{
if (res.g[j])
{
v ^= res.g[j];
k ^= d.g[j];
}
else
{
flag = false;
res.g[j] = v;
d.g[j] = k;
break ;
}
}
if (flag)
{
v = 0;
for (int j = L; j >= 0; --j)
if (k >> j & 1)
v ^= a.g[j];
c.Insert(v);
}
}
return c;
}
};
inline bool Insert(int t, ll v)
{
s[t] = s[t - 1];
p[t] = p[t - 1];
ll tmp = t;
for (int i = L; i >= 0; --i)
if (v >> i & 1)
{
if (p[t].g[i] < tmp)
{
std::swap(s[t].g[i], v);
std::swap(p[t].g[i], tmp);
}
v ^= s[t].g[i];
}
else
{
s[t].g[i] = v;
p[t].g[i] = tmp;
return true;
}
s[t].flag0 = true;
return false;
}
给出递推式 f n = a f n − 1 + b f n − 2 f_n = a f_{n - 1} + b f_{n - 2} fn=afn−1+bfn−2,已知 f 0 , f 1 f_0, f_1 f0,f1,求 f n f_n fn 的通项公式。
结论 设 x 1 , x 2 x_1, x_2 x1,x2 为方程 x 2 − a x − b = 0 x^2 - ax - b = 0 x2−ax−b=0 的两根(可以为复数)。
证明(实际可用基础的生成函数证明,以下是另一种证明方式)
尝试把递推式表示成等比数列的形式:
f n − x 1 f n − 1 = x 2 ( f n − 1 − x 1 f n − 2 ) f n = ( x 1 + x 2 ) f n − 1 − x 1 x 2 f n − 2 \begin{aligned}f_n - x_1 f_{n - 1} &= x_2(f_{n - 1} - x_1f_{n-2})\\f_n &= (x_1 + x_2) f_{n - 1} - x_1x_2 f_{n - 2} \\\end{aligned} fn−x1fn−1fn=x2(fn−1−x1fn−2)=(x1+x2)fn−1−x1x2fn−2
可以列出一个方程组:
{ x 1 + x 2 = a x 1 x 2 = − b \begin{cases}x_1 + x_2 = a\\x_1 x_2 = -b\\\end{cases} {x1+x2=ax1x2=−b
由韦达定理得, x 1 , x 2 x_1,x_2 x1,x2 是方程 x 2 − a x − b = 0 x^2 - ax - b = 0 x2−ax−b=0 的两根。设 c = f 1 − x 1 f 0 c = f_1 - x_1f_0 c=f1−x1f0,可列出 n n n 个方程:
{ f 1 − x 1 f 0 = c f 2 − x 1 f 1 = c x 2 f 3 − x 1 f 2 = c x 2 2 … f n − x 1 f n − 1 = c x 2 n − 1 \begin{cases}f_1 - x_1 f_0 &= c \\f_2 - x_1 f_1 &= c x_2 \\f_3 - x_1 f_2 &= c x_2^2 \\&…\\f_n - x_1 f_{n - 1} &= c x_2 ^{n - 1} \\\end{cases} ⎩ ⎨ ⎧f1−x1f0f2−x1f1f3−x1f2fn−x1fn−1=c=cx2=cx22…=cx2n−1
将第 i i i 个方程乘上 x 1 n − i x_1^{n - i} x1n−i,然后将所有方程相加,得到:
f n − x 1 n f 0 = c x 1 n − 1 ∑ i = 0 n − 1 ( x 2 x 1 ) i \begin{aligned}f_n - x_1^n f_0 = cx_1^{n - 1} \sum \limits_{i = 0}^{n - 1}\left(\frac{x_2}{x_1}\right)^{i}\\\end{aligned} fn−x1nf0=cx1n−1i=0∑n−1(x1x2)i
若 x 1 = x 2 x_1 = x_2 x1=x2,此时 A = f 0 , B = c x 1 A = f_0, B = \frac{c}{x_1} A=f0,B=x1c:
f n − x 1 n f 0 = c n x 1 n − 1 f n = c n x 1 n − 1 + x 1 n f 0 f n = ( f 0 + c x 1 n ) x 1 n \begin{aligned}f_n - x_1^n f_0 &= cnx_1^{n - 1}\\f_n &= cnx_1^{n - 1} + x_1^nf_0\\f_n &= \left(f_0 + \frac{c}{x_1} n \right) x_1^n \\\end{aligned} fn−x1nf0fnfn=cnx1n−1=cnx1n−1+x1nf0=(f0+x1cn)x1n
若 x 1 ≠ x 2 x_1 \neq x_2 x1=x2,由等比数列求和, A = f 0 − c x 2 − x 1 , B = c x 2 − x 1 A = f_0 - \frac{c}{x_2 - x_1}, B = \frac{c}{x_2 - x_1} A=f0−x2−x1c,B=x2−x1c:
f n − x 1 n f 0 = c x 1 n − 1 ( x 2 x 1 ) n − 1 x 2 x 1 − 1 f n = c x 2 n − x 1 n x 2 − x 1 + x 1 n f 0 f n = ( f 0 − c x 2 − x 1 ) x 1 n + c x 2 − x 1 x 2 n \begin{aligned}f_n - x_1^n f_0 &= cx_1^{n - 1} \frac{\left( \frac{x_2}{x_1}\right)^{n} - 1}{\frac{x_2}{x_1} - 1}\\f_n &= c \frac{x_2^n - x_1^n}{x_2 - x_1} + x_1^n f_0 \\f_n &= \left(f_0 - \frac{c}{x_2 - x_1} \right)x_1^n + \frac{c}{x_2 - x_1}x_2^n\\\end{aligned} fn−x1nf0fnfn=cx1n−1x1x2−1(x1x2)n−1=cx2−x1x2n−x1n+x1nf0=(f0−x2−x1c)x1n+x2−x1cx2n
证明 先证明此时一定存在 A A A 的分解方案。
记 A k A_k Ak 表示 A A A 前 k k k 行 k k k 列构成的子矩阵,则 D k = det ( A k ) D_k = \text{det}(A_k) Dk=det(Ak)。
由行列式的定义可知,若我们每次通过第三种初等行变换将 A k ( 1 ≤ k ≤ n − 1 ) A_k(1\le k \le n - 1) Ak(1≤k≤n−1) 化为上三角矩阵,则 A k A_k Ak 对角线上的元素一定不为 0。
因此,通过第三种初等行变换我们一定能将 A A A 化为上三角矩阵 U U U,则有: P l P l − 1 … P 1 A = U ⇔ A = ( P l P l − 1 … P 1 ) − 1 U P_{l}P_{l - 1}\dots P_1 A = U \Leftrightarrow A = (P_{l} P_{l - 1} \dots P_1)^{-1}U PlPl−1…P1A=U⇔A=(PlPl−1…P1)−1U
取 L = ( P l P l − 1 … P 1 ) − 1 = P 1 − 1 … P l − 1 − 1 P l − 1 L = (P_lP_{l - 1}\dots P_1)^{-1} = P_1^{-1}\dots P_{l - 1}^{-1}P_l^{-1} L=(PlPl−1…P1)−1=P1−1…Pl−1−1Pl−1,由于第三种初等行变换对应的初等矩阵及其逆均为单位下三角矩阵,故 L L L 也一定也为单位下三角矩阵,则我们构造出了一组 A A A 的分解方案。
再证明分解方案的唯一性,分以下两种情况讨论:
若 A A A 可逆,
- 假设分解不唯一,即 A = L 1 U 1 = L 2 U 2 A = L_1U_1 = L_2U_2 A=L1U1=L2U2,则 L 1 , U 1 , L 2 , U 2 L_1,U_1,L_2,U_2 L1,U1,L2,U2 均可逆,则有 U 1 U 2 − 1 = L 1 − 1 L 2 U_1U_2^{-1} = L_1^{-1}L_2 U1U2−1=L1−1L2,由于 U 1 U 2 − 1 U_1U_2^{-1} U1U2−1 是上三角矩阵, L 1 − 1 L 2 L_1^{-1}L_2 L1−1L2 是单位下三角矩阵,有 U 1 U 2 − 1 = L 1 − 1 L 2 = E U_1U_2^{-1} = L_1^{-1}L_2 = E U1U2−1=L1−1L2=E,所以 L 1 = L 2 , U 1 = U 2 L_1 = L_2, U_1 = U_2 L1=L2,U1=U2,与假设矛盾。
若 A A A 不可逆,
由分块矩阵相关理论,可知: A = ( A n − 1 α β T a n , n ) = ( L n − 1 0 l T 1 ) ( U n − 1 u 0 T 0 ) A = \left( \begin{matrix} A_{n - 1}& \alpha\\ \beta^T& a_{n,n} \\ \end{matrix} \right) = \left( \begin{matrix} L_{n - 1}& 0\\ l^T & 1\\ \end{matrix} \right) \left( \begin{matrix} U_{n - 1}& u \\ 0^T& 0\\ \end{matrix} \right) A=(An−1βTαan,n)=(Ln−1lT01)(Un−10Tu0)
因而可得到以下关系式: A n − 1 = L n − 1 U n − 1 α = L n − 1 u ⇔ u = L n − 1 − 1 α β T = l T U n − 1 ⇔ l T = β T U n − 1 − 1 \begin{aligned} A_{n - 1} &= L_{n - 1}U_{n - 1}\\ \alpha = L_{n - 1}u &\Leftrightarrow u = L_{n - 1}^{-1} \alpha\\ \beta^T = l^TU_{n - 1} &\Leftrightarrow l^T = \beta^TU_{n - 1}^{-1}\\ \end{aligned} An−1α=Ln−1uβT=lTUn−1=Ln−1Un−1⇔u=Ln−1−1α⇔lT=βTUn−1−1
由可逆情况的证明, L n − 1 , U n − 1 L_{n - 1},U_{n - 1} Ln−1,Un−1 是唯一的,故 u , l T u, l^T u,lT 也可唯一确定,该情况得证。
下面给出 L , U L,U L,U 的计算方法,显然有 l i , j = u j , i = 0 ( j > i ) , l i , i = 1 l_{i,j} = u_{j,i} = 0(j > i), l_{i,i} = 1 li,j=uj,i=0(j>i),li,i=1。
当 i ≤ j i \le j i≤j 时,由 a i , j = ∑ k = 1 i l i , k u k , j = ∑ k = 1 i − 1 l i , k u k , j + u i , j a_{i,j} = \sum \limits_{k = 1}^{i}l_{i,k}u_{k,j} = \sum\limits_{k = 1}^{i - 1}l_{i,k}u_{k,j}+u_{i,j} ai,j=k=1∑ili,kuk,j=k=1∑i−1li,kuk,j+ui,j,得 u i , j = a i , j − ∑ k = 1 i − 1 l i , k u k , j u_{i,j} = a_{i,j} - \sum \limits_{k = 1}^{i - 1}l_{i,k}u_{k,j} ui,j=ai,j−k=1∑i−1li,kuk,j,特别地,当 i = 1 i = 1 i=1 时,有 u i , j = a i , j u_{i,j} = a_{i,j} ui,j=ai,j。
当 i > j i > j i>j 时,由 a i , j = ∑ k = 1 j l i , k u k , j = ∑ k = 1 j − 1 l i , k u k , j + l i , j u j , j a_{i,j} = \sum\limits_{k = 1}^{j}l_{i,k}u_{k,j} = \sum \limits_{k = 1}^{j - 1}l_{i,k}u_{k,j} + l_{i,j}u_{j,j} ai,j=k=1∑jli,kuk,j=k=1∑j−1li,kuk,j+li,juj,j,得 l i , j = a i , j − ∑ k = 1 j − 1 l i , k u k , j u j , j l_{i,j} = \frac{a_{i,j} - \sum \limits_{k = 1}^{j - 1}l_{i,k}u_{k,j}}{u_{j,j}} li,j=uj,jai,j−k=1∑j−1li,kuk,j,特别地,当 j = 1 j = 1 j=1 时,有 l i , j = a i , j u j , j l_{i,j} = \frac{a_{i,j}}{u_{j,j}} li,j=uj,jai,j。
套用上式递推计算即可,时间复杂度 O ( n 3 ) \mathcal O(n^3) O(n3)。
inline void LU_Factorization(double (*a)[N], int n)
{
double b[N][N]; //由于 L,U 均为三角矩阵,可将两者同时存于一个矩阵中
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (i <= j)
{
b[i][j] = a[i][j];
for (int k = 1; k < i; ++k)
b[i][j] -= b[i][k] * b[k][j];
}
else
{
b[i][j] = a[i][j];
for (int k = 1; k < j; ++k)
b[i][j] -= b[i][k] * b[k][j];
if (fabs(b[j][j]) <= eps)
{
puts("No Solution");
return ;
}
b[i][j] /= b[j][j];
}
}