You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

332 lines
23 KiB
TeX

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

\documentclass[]{cpp}
\title{省选基础算法}
\author{雷宇辰}
\begin{document}
\setcounter{page}{0}
\maketitle
\begin{center}\includegraphics[height=20cm]{assets/banner.png}\end{center}
\newpage
\tableofcontents
\newpage
\setcounter{page}{1}
\section{day1 图论}
\subsection{有向图强连通分量的 Tarjan 算法}
\paragraph{定义}
\textbf{有向图$G$}中,如果两个顶点$u,v$间存在一条路径$u$$v$的路径且也存在一条$v$$u$的路径,则称这两个顶点$u,v$\textbf{强连通的(strongly connected)}。如果有向图$G$的每两个顶点都强连通,称$G$是一个\textbf{强连通图}。有向非强连通图的 极大强连通子图,称为\textbf{强连通分量(strongly connected components)}。若将有向图中的强连通分量都缩为一个点,则原图会形成一个 DAG有向无环图
\subparagraph{极大强连通子图}
$G$是一个极大强连通子图当且仅当$G$是一个强连通子图且不存在另一个强连通子图$G'$使得$G$$G'$的真子集。
\paragraph{Tarjan 算法}
定义$dfn(u)$为结点$u$搜索的次序编号,给出函数$low(u)$使得\\
$low(u) = min$
\\$\{$\\
\verb| |$dfn(u),$\\
\verb| |$low(v),$ \quad $(u,v)$为树枝边,$u$$v$的父结点\\
\verb| |$dfn(v)\;$ \quad $(u,v)$为后向边或指向栈中结点的横叉边
\\$\}$\\
当结点$u$的搜索过程结束后,若$dfn(u)=low(u)$,则以$u$为根的搜索子树上所有还在栈中的结点是一个强连通分量。
\subparagraph{代码}$\\$
\codeinput[tarjan - SCC]{assets/day1/tarjan-scc.cpp}
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=2186}{POJ2186}/\href{http://www.lydsy.com/JudgeOnline/problem.php?id=1051}{BZOJ1051} - Popular Cows} 双倍的快乐
\codeinput[Popular Cows]{assets/day1/poj2186.cpp}
\subparagraph{\href{http://poj.org/problem?id=3180}{POJ3180} - The Cow Prom} The $N (2 <= N <= 10,000)$ cows are so excited.
\codeinput[The Cow Prom]{assets/day1/poj3180.cpp}
\subparagraph{\href{http://poj.org/problem?id=3180}{POJ1236} - Network of Schools} 强连通分量缩点求出度为0的和入度为0的分量个数
\codeinput[Network of Schools]{assets/day1/poj1236.cpp}
\subsection{图的割点、桥与双连通分量}
\paragraph{定义}
\subparagraph{点连通度与边连通度}
在一个\textbf{无向连通图}中,如果有一个顶点集合$V$,删除顶点集合$V$,以及与$V$中顶点相连(至少有一端在$V$中)的所有边后,原图\textbf{不连通},就称这个点集$V$\textbf{割点集合}\\
一个图的\textbf{点连通度}的定义为:最小割点集合中的顶点数。\\
类似的,如果有一个边集合,删除这个边集合以后,原图不连通,就称这个点集为\textbf{割边集合}
\subparagraph{双连通图、割点与桥}
如果一个无向连通图的\textbf{点连通度大于$1$},则称该图是\textbf{点双连通的(point biconnected)},简称双连通或重连通。一个图有\textbf{割点},当且仅当这个图的点连通度为$1$,则割点集合的唯一元素被称为\textbf{割点(cut point)},又叫关节点(articulation point)。一个图可能有多个割点。\\
如果一个无向连通图的\textbf{边连通度大于$1$},则称该图是\textbf{边双连通的(edge biconnected)},简称双连通或重连通。一个图有\textbf{},当且仅当这个图的边连通度为$1$,则割边集合的唯一元素被称为\textbf{桥(bridge)},又叫关节边(articulation edge)。一个图可能有多个桥。\\
可以看出,点双连通与边双连通都可以简称为双连通,它们之间是有着某种联系的,下文中提到的双连通,均既可指点双连通,又可指边双连通。(但这并不意味着它们等价)\\
双连通分量(分支):在图$G$的所有子图$G'$中,如果$G'$是双连通的,则称$G'$为双连通子图。如果一个双连通子图$G'$它不是任何一个双连通子图的真子集,则$G'$为极大双连通子图。双连通分量(biconnected component),或重连通分量,就是图的极大双连通子图。特殊的,点双连通分量又叫做块。
\paragraph{Tarjan 算法}
给出函数$low(u)$使得\\
$low(u) = min$
\\$\{$\\
\verb| |$dfn(u),$\\
\verb| |$low(v),$ \quad $(u,v)$为树枝边(父子边)\\
\verb| |$dfn(v)\;$ \quad $(u,v)$为后向边(返祖边) 等价于$dfn(v)<dfn(u)$$v$不为$u$的父亲结点
\\$\}$\\
\subparagraph{代码}$\\$
\codeinput[tarjan - BCC]{assets/day1/tarjan-bcc.cpp}
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=3177}{POJ3177} - Redundant Paths}
将一张有桥图通过加边变成边双连通图,至少要加$\frac{leaf+1}{2}$条边。
\codeinput[Redundant Paths]{assets/day1/poj3177.cpp}
\subparagraph{\href{http://poj.org/problem?id=1523}{POJ1523} - SPF}
求割点与删除这个点之后有多少个连通分量
\codeinput[Redundant Paths]{assets/day1/poj1523.cpp}
\subparagraph{\href{http://poj.org/problem?id=2942}{POJ2942} - Knights of the Round Table}
这题过于复杂,我来先给个\href{http://blog.csdn.net/lyy289065406/article/details/6756821}{别人的题解}。然后是我自己的实现(仿佛还是没看懂。
\\ //实现被狗吃了
%\codeinput[Knights of the Round Table]{assets/day1/poj2942.cpp}
\subsection{2-SAT}
\paragraph{定义}
给定一个布尔方程,判断是否存在一组布尔变量的取值方案,使得整个方程值为真的问题,被称为布尔方程的可满足性问题(SAT)。SAT问题是NP完全的但对于一些特殊形式的SAT问题我们可以有效求解。\\
我们将下面这种布尔方程称为合取范式:
$$(a\lor b\lor c\lor\cdots)\land(d\lor e\lor f\lor\cdots)\land\cdots$$
其中$a,b,c,\cdots$称为文字,它是一个布尔变量或其否定。像$(a\lor b\lor c\lor\cdots)$这样用$\lor$连接的部分称为子句。如果合取范式的每个子句中的文字个数都不超过两个那么对应的SAT问题又称为\textbf{2-SAT}问题。
\paragraph{解法}
对于给定的\textbf{2-SAT}问题,首先利用$\Rightarrow$将每个子句$(a\lor b)$改写成等价形式$(\neg a\Rightarrow b\land a\Rightarrow\neg b)$.这样原布尔公式就变成了把$a\Rightarrow b$形式的布尔公式用$\land$连接起来的形式。\\
对每个布尔变量$x$构造两个顶点分别代表$x$$\neg x$。以$\Rightarrow$关系为边建立有向图。若在此图中$a$点能到达$b$点,就表示$a$为真时$b$也一定为真。因此该图中同一个强连通分量中所含的所有变量的布尔值均相同。\\
若存在某个变量$x$,代表$x$$\neg x$的两个顶点在同一个强连通分量中,则原布尔表达式的值无法为真。\\
反之若不存在这样的变量,那么我们先将原图中所有的强连通分量缩为一个点,构出一个新图,新图显然是一个拓扑图,我们求出它的一个拓扑序。那么对于每个变量$x$\textbf{$$x\text{所在的强连通分量(新图中的点)的拓扑序在}\neg x\text{所在的强连通分量之后}\Leftrightarrow x\text{为真}$$}就是一组合适布尔变量赋值。注意到 Tarjan 算法所求的强连通分量就是按拓扑序的逆序得出的,因此不需要真的缩点建新图求拓扑序,直接利用强连通分量的编号来当做顺序即可。
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=3648}{POJ3648} - Wedding}
Additionally, there are several pairs of people conducting adulterous relationships (both different-sex and same-sex relationships are possible)
\codeinput[adulterous relationships]{assets/day1/poj3648.cpp}
\subparagraph{\href{http://poj.org/problem?id=3678}{POJ3678} - Katu Puzzle} 我什么时候做过这个题?
\codeinput[Katu Puzzle]{assets/day1/poj3678.cpp}
\subparagraph{\href{http://poj.org/problem?id=2749}{POJ2749} - Building roads} 杀光奶牛问题就会得到解决
\codeinput[Building roads]{assets/day1/poj2749.cpp}
\subsection{欧拉回路}
\paragraph{定义}
$G=(V,E)$是一个图。
\subparagraph{欧拉回路}$G$中经过\textbf{每条边一次}并且\textbf{仅一次}的回路称作欧拉回路。
\subparagraph{欧拉路径}$G$中经过\textbf{每条边一次}并且\textbf{仅一次}的路径称作欧拉路径。
\subparagraph{欧拉图} 存在\textbf{欧拉回路}的图称为欧拉图。
\subparagraph{半欧拉图} 存在欧拉路径但不存在欧拉回路的图称为半欧拉图。
\paragraph{性质与定理}
以下不加证明的给出一些定理\quad\sout{(因为我懒得抄讲义了}
\subparagraph{定理 1} 无向图$G$为欧拉图,当且仅当$G$为连通图且所有顶点的度为偶数。
\subparagraph{推论 1} 无向图$G$为半欧拉图,当且仅当$G$为连通图且除了两个顶点的度为奇数之外,其它所有顶点的度为偶数。
\subparagraph{定理 2} 有向图$G$为欧拉图,当且仅当$G$的基图\footnote{忽略有向图所有边的方向,得到的无向图称为该有向图的基图。}连通,且所有顶点的入度等于出度。
\subparagraph{推论 2} 有向图$G$为半欧拉图,当且仅当$G$的基图连通,且存在顶点$u$的入度比出度大1、$v$的入度比出度小1其它所有顶点的入度等于出度。
\paragraph{解法}
由此可以得到以下求欧拉图$G$的欧拉回路的算法:
\begin{enumerate}
\item 在图$G$中任意找一个回路$C$
\item 将图$G$中属于回路$C$的边删除
\item 在残留图的各极大连通子图中分别寻找欧拉回路。
\item 将各极大连通子图的欧拉回路合并到$C$中得到图$G$的欧拉回路。
\end{enumerate}
该算法的伪代码如下:
\begin{verbatim}
void dfs(u)
{
for (edge e : edges[u])
if (!flag[e])
{
flag[e] = true;
flag[rev(e)] = true; //如果图 G 是有向图则删去本行
dfs(e.to);
S.push(v);
}
}
\end{verbatim}
最后依次取出栈$S$每一条边而得到图$G$的欧拉回路(也就是边出栈序的逆序)。由于该算法执行过程中每条边最多访问两次,因此该算法的时间复杂度为$O(|E|)$
\paragraph{练习题}
\subparagraph{\href{http://uoj.ac/problem/117}{UOJ117} - 欧拉回路}
混合两个子任务使代码风格变得鬼畜起来。
\codeinput[Building roads]{assets/day1/uoj117.cpp}
\section{day2 字符串(一)}
\subsection{KMP}
\paragraph{算法介绍} 用来在线性时间内匹配字符串
\paragraph{算法流程}
我觉得鏼鏼鏼在WC上讲的比较清楚于是我开始抄讲义。\\
\textbf{字符串:} $s[1\ldots n]$, $|s| = n$\\
\textbf{子串:} $s[i\ldots j] = s[i]s[i + 1]\cdots[j]$\\
\textbf{前缀:} $pre(s,x) = s[1\ldots x]$, 后缀:$suf(s,x) = s[n x + 1\ldots n]$\\
$0 \leq r \le |s|, pre(s,r) = suf(s,r)$, 就称 $pre(s,r)$$s$\textbf{border}\\
KMP算法的第一步主要做这么一件事$O(n)$时间求出数组$next[1\ldots n]$, 其中$next[i]$表示前缀$s[1\ldots i]$的最大 border 长度。
于是可以知道$s$的所有 border 长度为${next[n],next[next[n]],\cdots}$,我想这是显然的,于是不加证明的在这里给出。\\
第二步就是匹配,如果失配了就把模式串的当前位置指针$i$跳到$next[i]$处然后继续匹配,然后就好了。
\paragraph{算法实现}$\\$
\codeinput[genNext]{assets/day2/kmp-genNext.cpp}
\codeinput[Find]{assets/day2/kmp-Find.cpp}
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=3461}{POJ3461} - Oulipo} 求出所有匹配位置
\codeinput[Oulipo]{assets/day2/poj3461.cpp}
\subparagraph{\href{http://poj.org/problem?id=2406}{POJ2406} - Power Strings} $next$数组的奇妙性质
\codeinput[Power Strings]{assets/day2/poj2406.cpp}
\subparagraph{\href{http://codeforces.com/problemset/problem/526/D}{CF526D} - Om Nom and Necklace} 啥?
\codeinput[Om Nom and Necklace]{assets/day2/CF526D.cpp}
讲道理我KMP真的学的不是很明白望各位dalao给予指导。
\subsection{Trie}
\paragraph{简介}
字典树,也称 Trie、字母树指的是某个字符串集合对应的形如下图的有根树。树的每条边上对应有恰好一个字符每个顶点代表从根到该节点的路径所对应的字符串将所有经过的边上的字符按顺序连接起来
\paragraph{实现}
\codeinput[Trie - impl]{assets/day2/trieImpl.cpp}
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=3630}{POJ3630} - Phone List}
若插入过程中,有某个经过的节点带有串结尾标记,则之前插入的某个串是当前串的前缀。
\codeinput[Oulipo]{assets/day2/poj3630.cpp}
\subparagraph{\href{http://poj.org/problem?id=2945}{POJ2945} - Find the Clones}
$n$个基因片段,每个长度为$m$,输出$n$行表示重复出现$i$$(1 \leq i \leq n)$的基因片段的个数
\codeinput[Find the Clones]{assets/day2/poj2945.cpp}
\subsection{AhoCorasick Automaton}
\paragraph{简介}
多模式串字符串匹配Trie上的KMP其中$next$数组变成了$fail$指针,功能相同。
\paragraph{实现}
Trie的实现上文已经出现所以此处不再重复。
\codeinput[buildFail]{assets/day2/AC-buildFail.cpp}
\paragraph{练习题}
\subparagraph{\href{http://acm.hdu.edu.cn/showproblem.php?pid=2222}{HDU2222} - Keywords Search}
AC 自动机模板题,注意统计答案时,每个节点只能统计一次不要重复统计。
\codeinput[Keywords Search]{assets/day2/hdu2222.cpp}
\subsection{Manacher}
求出字符串每一位的回文半径,算法流程奥妙重重,不易让常人理解,然后我就抄了份板子改了改,然后就比讲义上的标程快了$20\%$
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=3974}{POJ3974} - Palindrome}
Manacher 模板题
\codeinput[Palindrome]{assets/day2/poj3974.cpp}
\section{day3 简单数学}
说是简单数学其实我后半部分也没看懂等明天来补欠债。20170215\\
\subsection{整除及剩余}
\paragraph{整除定义}
$a,b$是两个整数,且$b\neq0$.如果存在整数$c$,使得$a=bc$,则称$a$$b$整除,或$b$整除$a$,记作$b|a$。此时,又称$a$$b$的倍数,$b$$a$的因子。
\paragraph{整除的基本性质}
\begin{enumerate}
\item $a|b \land a|c \Rightarrow a|(b+c)$
\item $a|b \Rightarrow \forall c\in\mathbb{Z},\ a|bc$
\item $a|b \land b|c \Rightarrow a|c$
\end{enumerate}
\paragraph{同余基本定义和定理}
\subparagraph{定义1带余除法}
$$\forall a\in\mathbb{Z},b\in\mathbb{Z^{*}}\to\exists q,r\in\mathbb{Z},a=qb+r,r\in [0,|b|)$$
\subparagraph{定义2同余}
$$a\!\!\!\!\mod m = b\!\!\!\!\mod m \iff a\equiv b\!\!\!\!\pmod{m}$$
\subparagraph{定义3剩余类}
$$\mathbf{A_i}=\{x|x\in\mathbb{Z}\land x\!\!\!\!\mod{m} = i\}\to\forall a,b\in\mathbf{A_i},a\equiv b\!\!\!\!\pmod{m}$$
\subparagraph{定义4完系}
$$\{a_1\!\!\!\!\mod m,a_2\!\!\!\!\mod m,\ldots,a_n\!\!\!\!\mod m\}=\{0,1,2,\ldots,m-1\}$$
\subparagraph{定理1}
$$a\equiv b\!\!\!\!\pmod{m}\iff\exists k\in\mathbb{Z},a=b+km\iff m|(a-b)$$
\subparagraph{定理2} 同余关系是等价关系
\begin{enumerate}
\item $a\equiv a\pmod{m}$
\item $a\equiv b\pmod{m}\Rightarrow b\equiv a\pmod{m}$
\item $a\equiv b\pmod{m} \;\land\; b\equiv c\pmod{m}\Rightarrow a\equiv c\pmod{m}$
\end{enumerate}
\subparagraph{定理3} 同余的三则运算\\
$a,b,c\in\mathbb{R},m\in\mathbb{N^*}, a\equiv b\pmod{m} \Rightarrow$
\begin{enumerate}
\item $a+c\equiv b+c\pmod{m}$
\item $a-c\equiv b-c\pmod{m}$
\item $ac\equiv bc\pmod{m}$
\end{enumerate}
\subparagraph{定理4} 同余式的三则运算\\
$a,b,c\in\mathbb{R},m\in\mathbb{N^*}, a\equiv b\pmod{m} \land c\equiv d\pmod{m} \Rightarrow$
\begin{enumerate}
\item $ax+cy\equiv bx+dy\pmod{m}\qquad x,y\in\mathbb{Z}$
\item $ac\equiv bd\pmod{m}$
\item $a^n\equiv b^n\pmod{m}\qquad n\in\mathbb{N^*}$
\item $f(a)\equiv f(b)\pmod{m}\qquad f(x)$为任一整系数多项式
\end{enumerate}
\subparagraph{定理5}
\begin{enumerate}
\item $a\equiv b\pmod{m}\land d|m \Rightarrow a\equiv b\pmod{d}$
\item $a\equiv b\pmod{m}\Rightarrow gcd(a,m)=gcd(b,m)$
\item $\forall i \in [1,n]\ ,\;a\equiv b\pmod{m_i} \iff a\equiv b\pmod{lcm(m_1,m_2,\ldots,m_n)}$
\end{enumerate}
\subsection{素数}
\paragraph{定义}
素数(质数)是大于$1$的正整数,并且除了$1$和它本身不能被其他正整数整除。大于$1$的非素数的正整数称为合数。
\paragraph{分布}
素数有无穷多个.如果使用$\pi(x)$表示小于一个正实数$x$的素数有多少个,那么有$$\lim\limits_{x\rightarrow{\infty}}\frac{\pi(x)}{x}=\ln{x}$$
\paragraph{算术基本定理/惟一分解定理}
$$n=\prod\limits_{i=1}^\infty p_i^{a_i} \qquad p_i\in\mathbb{P},\;a_i\in\mathbb{N}$$
\paragraph{判定}
$$n\in\mathbb{P}\iff\forall i\in[2,\sqrt{n}],\;i\nmid n$$
\paragraph{Eratosthenes 筛法} $ $
\codeinput[Eratosthenes Sieve]{assets/day3/Eratosthenes.cpp}
\paragraph{欧拉函数} 欧拉函数$\varphi(n)$指不超过$n$且与$n$互素的正整数的个数,其中$n$是一个正整数。
\subparagraph{欧拉函数的性质} $n=\prod\limits_{i=1}^m p_i^{a_i}\to\varphi(n)=\prod\limits_{i=1}^m\varphi(p_i^{a_i})$
\subparagraph{定理1} $p\in\mathbb{P}\iff\varphi(p)=p-1$
\subparagraph{定理2} $p\in\mathbb{P},\;a\in\mathbb{N_+}\Rightarrow\varphi(p^a)=p^{a}-p^{a-1}$
\subparagraph{定理3} $m,n\in\mathbb{N_+}\land gcd(m,n)=1\Rightarrow\varphi(mn)=\varphi(m)\varphi(n)$
\subparagraph{定理4} $n=\prod\limits_{i=1}^m p_i^{a_i}\to\varphi(n)=n\prod\limits_{i=1}^{m}(1-\frac{1}{p_i})$
\subparagraph{推论} $n\equiv1\pmod2\to\varphi(2n)=\varphi(n)$
\subparagraph{定理5} $n\in(2,+\infty)\bigcap\mathbb{Z}\Rightarrow\varphi(n)\equiv0\pmod2$
\subparagraph{定理6} $n\in\mathbb{N_+}\Rightarrow\sum\limits_{d|n}\varphi(n)=n$
\subparagraph{欧拉定理} $gcd(a,m)=1,a\in\mathbb{N_+},m\in[2,+\infty)\bigcap\mathbb{Z}\Rightarrow a^{\varphi(m)}\equiv1\pmod{m}$
\subparagraph{费马小定理} $m\in\mathbb{P}\Rightarrow a^{m-1}\equiv1\pmod{m}$
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=2689}{POJ2689} - Prime Distance} 暴力筛掉合数
\codeinput[Prime Distance]{assets/day3/poj2689.cpp}
\subparagraph{\href{http://poj.org/problem?id=3421}{POJ3421} - X-factor Chains} 质因子的排列组合
\codeinput[X-factor Chains]{assets/day3/poj3421.cpp}
\subparagraph{\href{http://poj.org/problem?id=3090}{POJ3090} - Visible Lattice Points} 欧拉函数
\codeinput[Visible Lattice Points]{assets/day3/poj3090.cpp}
\subsection{欧几里得算法}
\paragraph{最大公约数与最小公倍数}
\subparagraph{定义1}$a$$b$是两个整数,如果$d|a$$d|b$,则称$d$$a$$b$的公因子
\subparagraph{定义2}$a$$b$是两个不全为$0$的整数,称$a$$b$的公因子中最大的为$a$$b$的最大公因子,或最大公约数,记作$gcd(a,b)$
\subparagraph{定义3}$a$$b$是两个非零整数,称$a$$b$最小的正公倍数为$a$$b$的最小公倍数,记作$lcm(a,b)$
\paragraph{最大公约数与最小公倍数的性质}
\begin{enumerate}
\item $a|m \land b|m \Rightarrow lcm(a,b)|m$
\item $d|a \land d|b \Rightarrow d|gcd(a,b)$
\item $lcm(a,b)=\frac{ab}{gcd(a,b)}$
\item $m,a,b\in\mathbb{N_+}\to lcm(ma,mb)=m\times lcm(a,b)\ ,\;\ gcd(ma,mb)=m \times gcd(a,b)$
\end{enumerate}
\paragraph{计算方法}
\subparagraph{素因子分解法}
$$a=\prod\limits_{i=1}^{m}p_{i}^{r_i}\;,\quad\;b=\prod\limits_{i=1}^{m}p_{i}^{s_i}$$
于是 $$gcd(a,b)=\prod\limits_{i=1}^{m}p_{i}^{min(r_i,s_i)}\;,\quad\;lcm(a,b)=\prod\limits_{i=1}^{m}p_{i}^{max(r_i,s_i)}$$
\subparagraph{欧几里得算法1} $$gcd(a,b)=gcd(b,a\!\!\!\!\mod b)$$
\subparagraph{欧几里得算法2} $$gcd(a,b)=gcd(a,a-b)$$
\paragraph{拓展欧几里得算法} 不理解就记下来
\codeinput[exgcd]{assets/day3/exgcd.cpp}
\subsection{线性同余方程}
\paragraph{二元一次不定方程}
\subparagraph{定义1} $a,b,c\in\mathbb{Z},a\ne0,b\ne0$,那形如$ax+by=c$的方程称为二元一次不定方程。
\subparagraph{定理1}$a,b\in\mathbb{Z}$$d=gcd(a,b)$,如果$d|c$,那么方程存在无穷多个整数解,否则方程不存在整数解。
\subparagraph{定理2} 如果不定方程有解且特解为$x=x_0,y=y_0$那么方程的解可以表示为$$x=x_0+\frac{b}{d}t,y=y_0-\frac{a}{d}t,\mbox{其中}t\in\mathbb{Z}$$
\paragraph{同余方程与不定方程}$a>0$$b>0$的条件下,求二元一次方程$ax+by=c$的整数解等价于求一元线性同余方程$ax\equiv c\bmod{b}$的整数解
\paragraph{求一元线性同余方程}
要求$ax\equiv c\bmod{b}$,即为求$ax+my=b$的解。记$d=gcd(a,m)$,先使用拓展欧几里得求$ax+my=b$,如果$d\nmid b$则无解,否则$\mod m$意义下的解有$d$个,可以通过对其中某个解不断地加$\frac{m}{d}$得到。(这$d$个解的形式为$x_0+\frac{m}{d}t,\;t\in\mathbb{Z}$,其中$x_0$是已知的一个解)
\paragraph{中国剩余定理}
$m_1,m_2,m_3,\ldots,m_r$是两两互素的正整数,则同余方程组
\begin{equation}
\left\{
\begin{aligned}
& x\equiv a_1\pmod{m_1}\\
& x\equiv a_2\pmod{m_2}\\
& x\equiv a_3\pmod{m_3}\\
& \cdots\\
& x\equiv a_r\pmod{m_r}\\
\end{aligned}
\right.
\end{equation}
$\mod M=\prod\limits_1^r m$的唯一解,即为中国剩余定理。\\
$n=pq$$gcd(p,q)=1$,那么$x\mod p,x\mod q$的值确定后,$x\mod n$的值也会随之确定。
\subparagraph{算法说明}
$$M_i=\prod\limits_{j\ne i}m_j\to gcd(M_i,m_i)=1\Rightarrow \exists p_i,q_i,\,M_ip_i+m_iq_i=1$$
$$(e_i=M_i p_i)\equiv int(j==i)\pmod{m_i} \to \sum\limits_1^r e_i a_i\mod{\sum\limits_1^r m_i}\mbox{是方程的最小非负整数解}$$
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=1061}{POJ1061} - 蛤蛤的约会} +1s
\codeinput[蛤蛤的约会]{assets/day3/poj1061.cpp}
\subparagraph{\href{http://poj.org/problem?id=2142}{POJ2142} - The Balance}$ax+by=c$的一组解,使得$|x|+|y|$尽量小,在前者尽量小时$|ax|+|by|$尽量小
\codeinput[The Balance]{assets/day3/poj2142.cpp}
\subsection{逆元}
\paragraph{解一元线性同余方程}
$$gcd(a,m)=1\Rightarrow\exists x,ax\equiv1\pmod{m}$$
$$ax\equiv1\pmod{m}\iff\exists k\in\mathbb{Z},\,ax-km=1$$
\codeinput[\ ]{assets/day3/inv.cpp}
\paragraph{费马小定理}
$$\forall p\in\mathbb{P}\to x^p\equiv x\pmod{p}$$被称为费马小定理,若$p\nmid x$,有
$$x^{p-1}\equiv 1\pmod{p}$$于是有
$$\forall p\in\mathbb{P},x\in\mathbb{Z}\to x^{-1}\equiv x^{p-2}\pmod{p}$$
使用快速幂即可计算。
\subsection{待续:高次不定方程}
\subsection{原根}
\paragraph{}
$$n>1,a\in\mathbb{Z},gcd(a,n)=1\to\exists r\in[1,n],a^r\equiv1\pmod{n}$$ $r$的最小整数值称为$a$$n$的阶,记为$Ord_n(a)$
\paragraph{阶的性质}
$$gcd(a,n)=1,r=Ord_n(a),\forall N\in\{x|a^N\equiv1\pmod{n}\}\Rightarrow r|N$$
$$gcd(a,n)=1\Rightarrow Ord_n(a)|\varphi(n)$$
$$\mbox{特别的,}p\in\mathbb{P},gcd(a,p)=1\Rightarrow Ord_p(a)|p-1\mbox{,显然}\varphi(p)=p-1$$
\paragraph{原根} $n\in\mathbb{N_+},a\in\mathbb{Z},Ord_n(a)=\varphi(n)$,则称$a$为模$n$的一个原根,由阶的定义可知原根和$n$必然互质。
\paragraph{求质数$p$的原根算法}
暴力从小到大枚举$g\in\mathbb{N_+}$$\forall a\in\{x\;|\;x|p-1,x\in\mathbb{P}\},g^{\frac{p-1}{a}}\not\equiv1\pmod{p}$
\codeinput[Primitive Root]{assets/day3/proot.cpp}
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=1284}{POJ1284} - Primitive Roots} 如果$n\in\mathbb{N_+}$有一个原根,那么$n$一共有$\varphi(\varphi(n))$个不同余的原根
\codeinput[Primitive Roots]{assets/day3/poj1284.cpp}
\end{document}