记录平时遇到的一些知识点。
原根
阶:设\(a,p\)是整数且互质,那么满足\(a^n=1\mod p\)的最小整数\(n\)就称为\(a\)模\(p\)的阶。
原根:当\(a\)模\(m\)的阶为\(\varphi(m)\)时,就称\(a\)为模\(m\)的一个原根。
- 性质:假设\(g\)为模\(m\)的一个原根,那么满足\(g^1,g^2,\cdots,g^{p-1}\)模\(m\)的结果两两不相同。
- 模\(m\)有原根的充要条件:\(m=2,4,p^a,p^{2a}\),\(p\)为奇素数。
快速求原根:得到\(m-1\)的所有质因子\(p_1,p_2,\cdots,p_k\),从小到达枚举\(i\),若满足\(i^\frac{m-1}{p_j}\mod m =1\),则\(i\)不为原根。证明可通过裴蜀定理来证明,详见:传送门
二次剩余
- 定义:若存在一个\(x\),满足\(x^2=d\mod p\),则称\(d\)为模\(p\)的二次剩余。
- 勒让德记号:\(\big(\frac{a}{p}\big)\),表示\(a^\frac{p-1}{2}\)。
- 欧拉准则:
\[
\left(\frac{a}{p}\right) \equiv \left\{
\begin{aligned}
&1,a是模p的二次剩余且p不整除a\\
&-1,a是模p的非二次剩余\\
&0,p|a\\
\end{aligned}
\right.
\]
证明可参见:传送门
- 特别地,若满足\(p\mod 3\equiv4\),那么\(x^2\equiv d\mod p\)的解为\(x=\pm d^{\frac{p+1}{4}}\).
- 更多可参见:wiki
- 二次互反律:
- \(\left(\frac{q}{p}\right)\left(\frac{p}{q}\right)=(-1)^{\frac{(p-1)(q-1)}{4}}\),其中\(p,q\)为两个奇质数;
- 满足:\(\left(\frac{ab}{p}\right)=\left(\frac{a}{p}\right)\left(\frac{b}{p}\right)\);
- 同时,二次互反律还可以用来判断\(x\equiv p\mod q\)及\(x\equiv q\mod p\)可解的简单关系;
- 其它形式:\(\left(\frac{q}{p}\right)=\left(\frac{p}{q}\right)(-1)^{\frac{(p-1)(q-1)}{4}}\);
- 如果\(a\equiv b\),则有\(\left(\frac{a}{p}\right)=\left(\frac{b}{p}\right)\);
- 运用二次互反律可以将模数较大的判断是否存在二次剩余的情况拆成模数较小的情况,简化运算;
- 辅助定理:\(\left(\frac{2}{p}\right)=(-1)^{\frac{p^2-1}{8}},\left(\frac{-1}{p}\right)=(-1)^{\frac{p-1}{2}}\).
- 更多可参见:wiki
代码:Code
//求解x^2=n(mod p) const int moder = (int) 1e9 + 7; const int inv2 = (moder + 1) / 2; struct field2{ int x, y, a, p; field2():x(0), y(0), a(0), p(0){} field2(int x, int y, int a, int p):x(x), y(y), a(a), p(p){} field2 operator *(const field2 &f)const{ int retx = (1ll * x * f.x + 1ll * y * f.y % p * a) % p; int rety = (1ll * x * f.y + 1ll * y * f.x) % p; return field2(retx, rety, a, p); } field2 powermod(int exp)const{ field2 ret(1, 0, a, p), aux = *this; for ( ; exp > 0; exp >>= 1){ if (exp & 1){ ret = ret * aux; } aux = aux * aux; } return ret; } }; int powermod(int a, int exp, int moder){ int ret = 1; for ( ; exp; exp >>= 1){ if (exp & 1){ ret = 1ll * ret * a % moder; } a = 1ll * a * a % moder; } return ret; } int randint(int n){ return rand() % n; } vector <int> remain2(int a, int p){ //x^2 = a (mod p) if (!a || p == 2){ //特判 return {a, a}; } if (powermod(a, p - 1 >> 1, p) != 1){ //欧拉准则 return {}; } while (true){ field2 f(randint(p - 1) + 1, randint(p - 1) + 1, a, p); f = f.powermod(p - 1 >> 1); if (f.x){ continue; } int ret = powermod(f.y, p - 2, p); return {ret, p - ret}; } }
斐波那契系数
- 定义:
\[ {n\choose k}_F=\frac{F_nF_{n-1}\cdots F_{n-k+1}}{F_1F_2\cdots F_k} \] - 应用:\(F^{n-1}\)的递推系数可由\({nk\choose k}_F\)确定,但需要注意符号。
- 更多可参见:wiki
高斯二次项系数
- 定义:
\[ {m\choose r}_q=\left\{ \begin{aligned} &\frac{(1-q^m)(1-q^{m-1})\cdots (1-q^{m-r+1})}{(1-q)(1-q^2)\cdots (1-q^r)},&r\leq m\\ &0,&r>m \end{aligned} \right. \] - 记\([k]_q=1+q^1+\cdots +q^{k-1}\),那么有:\({m\choose r}_q=\frac{[m]_q[m-1]_q\cdots [m-r+1]_q}{[1]_q[2]_q\dots [r]_q},(r\leq m)\)。
- 组合数中的定义:\({m\choose r}_q\)的含义为从长度为\(m\)的串中选出\(r\)个为\(1\),其余为\(0\)的所有排列中的逆序对个数,类似于生成函数,假设最后得到的式子为\(1+a_1q^1+\cdots a_iq^i + \cdots + a_nq^n\),那么其含义为逆序对个数为\(i\)的串共有\(a_i\)种排列。这个可推广到任意多重集排列。
- 易知当\(q=1\)时,其等同于普通组合数。
类欧几里得
求\(\sum_{i=0}^{n}\lfloor\frac{ai+b}{c}\rfloor\).
推导过程如下:
- 若\(a\geq c\),那么式子可拆分为:\(\sum_{i=0}^{n}\lfloor\frac{(a\%c)i+b}{c}\rfloor+i\lfloor\frac{a}{c}\rfloor\),后面部分为等差数列,单独计算即可;
- 若\(b\geq c\),同理式子拆分为:\(\sum_{i=0}^{n}\lfloor\frac{ai+b\%c}{c}\rfloor+\lfloor\frac{a}{c}\rfloor\),后面部分直接算即可;
- 现在讨论\(a<c,b<c\)的情况:
\[ \begin{aligned} &\sum_{i=0}^{n}\lfloor\frac{ai+b}{c}\rfloor\\ =&\sum_{i=0}^{n}\sum_{j=1}^{\frac{ai+b}{c}}1\\ =&\sum_{i=0}^{n}\sum_{j=1}^{\frac{an+b}{c}}j\leq \lfloor\frac{ai+b}{c}\rfloor\\ =&\sum_{i=0}^{n}\sum_{j=1}^{\frac{an+b}{c}}ai\geq cj-b\\ =&\sum_{i=0}^{n}\sum_{j=1}^{\frac{an+b}{c}}i\geq \lceil\frac{cj-b}{a}\rceil\\ =&\sum_{i=0}^{n}\sum_{j=1}^{\frac{an+b}{c}}i\geq \lfloor\frac{cj-b+a-1}{a}\rfloor\\ \end{aligned} \]
交换求和符号,注意到每次\(i\)都是从\(0\)到\(n\),并且我们让\(j\)从\(0\)开始,那么有:
\[ \begin{aligned} &\sum_{j=1}^{\frac{an+b}{c}}n-\lfloor\frac{cj-b+a-1}{a}\rfloor+1\\ =&n\lfloor\frac{an+b}{c}\rfloor-\sum_{j=0}^{\lfloor\frac{an+b}{c}\rfloor-1}\lfloor\frac{cj-b+a+c-1}{a}\rfloor-1\\ =&n\lfloor\frac{an+b}{c}\rfloor-\sum_{j=0}^{\lfloor\frac{an+b}{c}\rfloor-1}\lfloor\frac{cj-b+c-1}{a}\rfloor\\ \end{aligned} \]
发现后面部分和我们一开始处理的是同一个问题,然后我们递归算下去就行了。
因为每次\((a,c)\)变为了\((c,a\%c)\),所以复杂度为\(O(logn)\)。
直观点来理解类欧的话,所求式子就是求一条直线为\(x,y\)轴所围成的梯形内部的整点个数。我们的做法就是首先将直线斜率变平缓,然后变换坐标系...依次处理下去,最后肯定直线斜率会趋近于\(0\)。
附上模板:Code
const int MOD = 1000000007, inv2 = (MOD + 1) / 2; ll f(ll n, ll a, ll b, ll c) { //sum_{i=0}^n (ai+b)/c if(a <= 0) return 0; if(a >= c || b >= c) { return (n * (n + 1) % MOD * inv2 % MOD * (a / c) % MOD + (n + 1) * (b / c) % MOD + f(n, a % c, b % c, c)) % MOD; } ll m = (a * n + b) / c; return (m * n % MOD - f(m - 1, c, c - b - 1, a) + MOD) % MOD; }
当然类欧还能解决其它的问题,我就不详细展开了~