数学问题笔记

思维题

CF1553F Pairwise Modulo

p k = ∑ i = 1 k ∑ j = 1 k a i   m o d   a j p_k=\sum_{i=1}^{k}\sum_{j=1}^{k}a_i \bmod a_j pk=i=1kj=1kaimodaj
求对于每个 i ∈ [ 1 , n ] i\in[1,n] i[1,n]

观察值域,记录每个数的出现次数,枚举数。

考虑递推 p k − p k − 1 = ? p_k-p_{k-1}=? pkpk1=?

考虑贡献,用树状树组维护即可。

时间复杂度 O ( n ln ⁡ n ) O(n \ln n) O(nlnn)

洛谷P1835 素数密度

L , R ∈ [ 1 , 2 31 ) L,R \in[1,2^{31}) L,R[1,231),不可能全部算出,观察发现 R − L ≤ 1 0 6 R-L\le 10^6 RL106,考虑先筛出 [ 2 , R ] [2,\sqrt{R}] [2,R ]内的所有质数,保证了 [ L , R ] [L,R] [L,R] 内的素数均能被筛出。再筛 [ L , R ] [L,R] [L,R],使 v s t ( v i s i t ) vst(visit) vst(visit) 数组整体偏移即可,大小只需开到 1 0 6 10^6 106,考虑到合数个数可在筛的过程中被计算,考虑用总共个数减去合数个数,即为答案。

注:第二层循环需从某个质数的整数倍开始筛起,不可从 L L L 开始。

整数分解定理

p p p 为质数, x = ∏ p i c i x=\prod p_{i}^{c_i} x=pici

最大公约数$

gcd ⁡ ( a , b ) = gcd ⁡ ( b , a − b ) \gcd(a,b)=\gcd(b,a-b) gcd(a,b)=gcd(b,ab)
gcd ⁡ ( a , b ) = gcd ⁡ ( b , a   m o d   b ) \gcd(a,b)=\gcd(b,a\bmod b) gcd(a,b)=gcd(b,amodb)
a b = gcd ⁡ ( a , b ) lcm ⁡ ( a , b ) ab=\gcd(a,b)\operatorname{lcm}(a,b) ab=gcd(a,b)lcm(a,b)
gcd ⁡ ( a , lcm ⁡ ( b , c ) ) = lcm ⁡ ( gcd ⁡ ( a , b ) , gcd ⁡ ( a , c ) ) \gcd(a,\operatorname{lcm}(b, c)) =\operatorname{lcm}(\gcd(a, b), \gcd(a, c)) gcd(a,lcm(b,c))=lcm(gcd(a,b),gcd(a,c))
lcm ⁡ ( a , gcd ⁡ ( b , c ) ) = gcd ⁡ ( lcm ⁡ ( a , b ) , lcm ⁡ ( a , c ) ) \operatorname{lcm}(a, \gcd(b, c)) = \gcd(\operatorname{lcm}(a, b), \operatorname{lcm}(a, c)) lcm(a,gcd(b,c))=gcd(lcm(a,b),lcm(a,c))
f f f 斐波那契数列, gcd ⁡ ( f n , f m ) = f gcd ⁡ ( n , m ) \gcd(f_n,f_m)=f_{\gcd(n,m)} gcd(fn,fm)=fgcd(n,m)

  • 辗转相除法 gcd ⁡ ( a , b ) = gcd ⁡ ( b , a   m o d   b ) \gcd(a,b)=\gcd(b,a \bmod b) gcd(a,b)=gcd(b,amodb)
  • 不涉及取余的方法,偶数集为 E E E,奇数集为 O O O { a ∈ E , b ∈ E , gcd ⁡ ( a , b ) = gcd ⁡ ( a 2 , b 2 ) a ∈ E , b ∈ O , gcd ⁡ ( a , b ) = gcd ⁡ ( a 2 , b ) a ∈ O , b ∈ E , gcd ⁡ ( a , b ) = gcd ⁡ ( a , b 2 ) a ∈ O , b ∈ O , gcd ⁡ ( a , b ) = gcd ⁡ ( b , a − b ) \begin{cases} a\in E,b\in E ,\gcd(a,b)=\gcd(\frac{a}{2},\frac{b}{2})\\a\in E ,b\in O ,\gcd(a,b)=\gcd(\frac{a}{2},b)\\a\in O,b\in E,\gcd(a,b)=\gcd(a,\frac{b}{2})\\a\in O,b\in O,\gcd(a,b)=\gcd(b,a-b)\end{cases} aE,bE,gcd(a,b)=gcd(2a,2b)aE,bO,gcd(a,b)=gcd(2a,b)aO,bE,gcd(a,b)=gcd(a,2b)aO,bO,gcd(a,b)=gcd(b,ab)

求形似 a x + b y = c ax+by=c ax+by=c 的不定方程

c ∤ gcd ⁡ ( a , b ) c\not |\gcd(a,b) cgcd(a,b) 时,无整数解。
通过拓展欧几里德求出 x 0 , y 0 x_0,y_0 x0,y0 满足 a x 0 + b y 0 = gcd ⁡ ( a , b ) ax_0+by_0=\gcd(a,b) ax0+by0=gcd(a,b),同时乘上 c gcd ⁡ ( a , b ) \frac{c}{\gcd(a,b)} gcd(a,b)c,特解为 { x b a s e = x 0 c gcd ⁡ ( a , b ) y b a s e = y 0 c gcd ⁡ ( a , b ) \begin{cases}x_{base}=\frac{x_0c}{\gcd(a,b)}\\y_{base}=\frac{y_0c}{\gcd(a,b)}\end{cases} {xbase=gcd(a,b)x0cybase=gcd(a,b)y0c d ∈ Z d\in Z dZ,通解为 { x = x b a s e + d b gcd ⁡ ( a , b ) y = y b a s e + d a gcd ⁡ ( a , b ) \begin{cases}x=x_{base}+\frac{db}{\gcd(a,b)}\\y=y_{base}+\frac{da}{\gcd(a,b)}\end{cases} {x=xbase+gcd(a,b)dby=ybase+gcd(a,b)da

求解同余方程 a x ≡ c ( m o d b ) ax\equiv c\pmod b axc(modb)

化为 a x + b y = c ax+by=c ax+by=c,求解该不定方程的解即可。

乘法逆元

费马小定理

p p p 为质数且 a , p a,p a,p 互质, a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod p ap11(modp)
a x ≡ 1 ( m o d p ) ⇒ x ≡ a p − 2 ≡ a − 1 ( m o d p ) ax\equiv 1\pmod p\Rightarrow x\equiv a^{p-2}\equiv a^{-1}\pmod p ax1(modp)xap2a1(modp),快速幂即可。

拓展欧几里德

a , p a,p a,p 互质,求解 a x + p y = 1 ax+py=1 ax+py=1 不定方程即可。

线性递推

x − 1 ≡ − ⌊ p x ⌋ × ( p   m o d   x ) − 1 ( m o d p ) x^{-1}\equiv-\lfloor \frac{p}{x}\rfloor\times(p \bmod x)^{-1}\pmod p x1xp×(pmodx)1(modp)

前后缀积

求解形似 ∑ i = 1 n x a i \sum_{i=1}^{n} \frac{x}{a_i} i=1naix
p r e i = ∏ j = 1 i a j pre_i=\prod_{j=1}^{i}a_j prei=j=1iaj s u f i = ∏ j = i n a j suf_i=\prod_{j=i}^{n}a_j sufi=j=inaj p r o = ∏ i = 1 n a i pro=\prod_{i=1}^{n}a_i pro=i=1nai ,原式化为 ∑ i = 1 n p r e i − 1 × x × s u f i + 1 p r o \sum_{i=1}^{n}\frac{pre_{i-1}\times x\times suf_{i+1}}{pro} i=1nproprei1×x×sufi+1

欧拉函数

待填坑。

线性同余方程

洛谷P1516 青蛙的约会

由题
s a + x v a ≡ s b + x v b ( m o d l ) s_a+xv_a\equiv s_b+xv_b\pmod l sa+xvasb+xvb(modl)移项得
( v a − v b ) x + l y = s b − s a (v_a-v_b)x+ly=s_b-s_a (vavb)x+ly=sbsa gcd ⁡ ( v a − v b , l ) ∣ ( s b − s a ) \gcd(v_a-v_b,l)\mid(s_b-s_a) gcd(vavb,l)(sbsa) 时有解,拓展欧几里得求出一组特解 ( x , y ) (x,y) (x,y),满足
( v a − v b ) x + l y = gcd ⁡ ( v a − v b , l ) (v_a-v_b)x+ly=\gcd(v_a-v_b,l) (vavb)x+ly=gcd(vavb,l)于是
x 0 = x ( s b − s a ) gcd ⁡ ( v a − v b , l ) x_0=\frac{x(s_b-s_a)}{\gcd(v_a-v_b,l)} x0=gcd(vavb,l)x(sbsa)即为原同余方程的一个解。于是可以得到原同余方程的解系
x = x 0 + k ( l gcd ⁡ ( v a − v b , l ) ) , k ∈ Z x=x_0+k(\frac{l}{\gcd(v_a-v_b,l)}),k\in Z x=x0+k(gcd(vavb,l)l),kZ所求为最小非负整数解
x m i n = x 0   m o d   l gcd ⁡ ( v a − v b , l ) x_{min} = x_0\bmod \frac{l}{\gcd(v_a-v_b,l)} xmin=x0modgcd(vavb,l)l

注: ( v a − v b ) (v_a-v_b) (vavb) 需为正数,从而 gcd ⁡ ( v a − v b , l ) \gcd(v_a-v_b,l) gcd(vavb,l) 才有意义。

洛谷P1052 过河

由于 n n n 的范围 1 ∼ 1 e 9 1\sim1e9 11e9,朴素的动态规划肯定不行。
考虑路径压缩,对于位于 x i x_i xi x j x_j xj 的两颗石子,在状态转移时,会产生许多无用的状态,可以证明(通过???),若每次走 p p p 步,则 p ( p − 1 ) p(p-1) p(p1) 步后的每一个点均可到达,所以得到路径压缩的方法
∣ x i − x j ∣ ← min ⁡ { ∣ x i − x j ∣ , p ( p − 1 ) } |x_i-x_j|\gets \min\{|x_i-x_j|,p(p-1)\} xixjmin{xixj,p(p1)}

线性同余方程组

洛谷P4777 拓展中国剩余定理

关于朴素的中国剩余定理不能解决各模数不互质的情况,考虑拓展中国剩余定理。

核心思想为合并同余方程。
{ x ≡ a 1 ( m o d b 1 ) x ≡ a 1 ( m o d b 1 ) x ≡ a 2 ( m o d b 2 )   ⋯ x ≡ a k ( m o d b k ) \begin{cases}x \equiv a_1\pmod {b_1}\\ x \equiv a_1\pmod {b_1}\\ x \equiv a_2\pmod {b_2}\\ \space\cdots\\ x \equiv a_k\pmod {b_k}\\\end{cases} xa1(modb1)xa1(modb1)xa2(modb2) xak(modbk)对于其中任意两组同余方程
{ x ≡ a i ( m o d b i ) x ≡ a j ( m o d b j ) \begin{cases}x\equiv a_i\pmod {b_i} \\ x\equiv a_j\pmod {b_j}\\\end{cases} {xai(modbi)xaj(modbj)等价于
x = b i y i + a i = b j y j + a j x=b_iy_i+a_i=b_jy_j+a_j x=biyi+ai=bjyj+aj移项得
b i y i − b j y j = a j − a i b_iy_i-b_jy_j=a_j-a_i biyibjyj=ajai利用拓展欧几里得求出该同余方程的最小整数解 ( y i 0 , y j 0 ) (y_{i0},y_{j0}) (yi0,yj0),从而得到对于这两个同余方程的 x x x 的最小非负整数解 x 0 = b i y i 0 + a i x_0=b_iy_{i0}+a_i x0=biyi0+ai 从而得到合并后的同余方程(即对于这两个同余方程 x x x 的解系)
x ≡ x 0 ( m o d lcm ⁡ ( b i , b j ) ) x\equiv x_0\pmod {\operatorname{lcm}(b_i,b_j)} xx0(modlcm(bi,bj))依次合并所有同余方程即可,最终答案为全部合并完后的 a a a

注:乘法运算有溢出可能,考虑龟速乘(当然手写高精也行只要你开心 )。

其他

矩阵

洛谷P1939 矩阵加速(数列)

矩阵加速线性递推模板。

前置知识:矩阵快速幂

对于函数
f n = a n − 1 f n − 1 + a n − 2 f n − 2 + ⋯ + a n − i f n − i f_n=a_{n-1}f_{n-1}+a_{n-2}f_{n-2}+\cdots +a_{n-i}f_{n-i} fn=an1fn1+an2fn2++anifni
A n − 1 = ∣ f n − 1 f n − 2 f n − 3 ⋮ f n − i ∣ A_{n-1}=\begin{vmatrix}f_{n-1}\\f_{n-2}\\f_{n-3 }\\ \vdots\\f_{n-i}\end{vmatrix} An1=fn1fn2fn3fni考虑构造一个 i i i 维矩阵
B = ∣ a n − 1 a n − 2 a n − 3 a n − 4 ⋯ a n − i + 1 a n − i 1 0 0 0 ⋯ 0 0 0 1 0 0 ⋯ 0 0 0 0 1 0 ⋯ 0 0 ⋮ ⋮ ⋮ ⋮ ⋱ ⋮ ⋮ 0 0 0 0 ⋯ 0 0 0 0 0 0 ⋯ 1 0 ∣ B=\begin{vmatrix}a_{n-1} & a_{n-2} &a_{n-3}&a_{n-4}& \cdots &a_{n-i+1}&a_{n-i}\\ 1 & 0 & 0 & 0&\cdots &0&0\\ 0 & 1 & 0 & 0&\cdots &0& 0\\ 0 & 0& 1& 0&\cdots &0&0\\ \vdots&\vdots&\vdots&\vdots&\ddots&\vdots&\vdots\\ 0&0&0&0&\cdots&0&0\\ 0&0 &0&0&\cdots&1&0\end{vmatrix} B=an110000an201000an300100an400000ani+100001ani00000使得
A n = A n − 1 × B = ∣ f n f n − 1 f n − 2 ⋮ f n − i + 1 ∣ A_n=A_{n-1}\times B=\begin{vmatrix}f_{n}\\f_{n-1}\\f_{n-2 }\\\vdots\\f_{n-i+1}\end{vmatrix} An=An1×B=fnfn1fn2fni+1使用矩阵快速幂维护即可,时间复杂度 O ( log ⁡ n ) O(\log n) O(logn)

对于不寻常的矩阵构造,考虑列表法,如下题。

TR的数列(无link)

填个坑。

洛谷P2388 斐波那契数列

斐波那契递推公式
{ f n = f n − 1 + f n − 2 f 2 n = ( f n + 1 ) 2 − ( f n − 1 ) 2 f 2 n + 1 = ( f n + 1 ) 2 + ( f n ) 2 \large\begin{cases}\large f_n=f_{n-1}+f_{n-2}\\f_{2n}=(f_{n+1})^2-(f_{n-1})^2\\ f_{2n+1}=(f_{n+1})^2+(f_{n})^2 \end{cases} fn=fn1+fn2f2n=(fn+1)2(fn1)2f2n+1=(fn+1)2+(fn)2
也可以考虑矩阵快速幂做法。

阶乘

洛谷P2388 阶乘之乘

∏ i = 1 n n ! \large \prod_{i=1}^{n}n! i=1nn!
末尾零的个数只与因数 10 10 10 的个数有关,而 10 10 10 的个数只与 5 5 5 2 2 2的个数有关,而 5 5 5 的个数一定小于 2 2 2 的个数,所以答案即为其因数 5 5 5 的个数。

线性枚举每一个数即可,时间复杂度 O ( n ) O(n) O(n),然而竟然有 O ( log ⁡ ( n ) ) O(\log (n)) O(log(n))的算法,只是我不会

附:快速计算阶乘.
f ( n ) = n ! = n ! ( n 2 ! ) × ( n 2 ! ) × ( n 2 ! ) 2 \large f(n)=n!=\frac{n!}{(\frac{n}{2}!)\times(\frac{n}{2}!)}\times (\frac{n}{2}!)^2 f(n)=n!=(2n!)×(2n!)n!×(2n!)2,时间复杂度 O ( log ⁡ n ) O(\log n) O(logn)

洛谷CF1542C StrangeFunction

直接枚举肯定会炸,于是打表,发现变化有规律。
c i = lcm ⁡ ( 1 , 2 , ⋯   , i ) c_i=\operatorname{lcm}(1,2,\cdots,i) ci=lcm(1,2,,i),发现每隔 c i c_i ci 就会出现一个 i + 1 i+1 i+1,每个点由较大数覆盖 。

//表
2 3 2 3 2 4 2 3 2 3 2 5 2 3 2 3 2 4 2 3 2 3 2 5

2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2----1
  3   3   3   3   3   3   3   3   3   3   3   3----2
          4           4           4           4----6
                      5                       5----12

预处理出 c i c_i ci,枚举每个 c i c_i ci 累加 n c i \frac{n} {c_i} cin 即可

洛谷P2181 对角线

对于求交点个数,交点即为线与线的交点,固定一个端点,对连接该点的 n − 3 n-3 n3 对角线, ( 逆时针 ) 第 i i i 条对角线左边有 i i i 个点,右边有 n − 2 − i n-2-i n2i 个点,单条对角线产生交点个数即为 ∑ i = 1 n − 3 i × ( n − 2 − i ) \large \sum_{i=1}^{n-3}{i}\times{(n-2-i)} i=1n3i×(n2i)
所有对角线产生的总个数为 n × ∑ i = 1 n − 3 i × ( n − 2 − i ) \large n\times \sum_{i=1}^{n-3}{i}\times{(n-2-i)} n×i=1n3i×(n2i)
考虑去重,对角线的交点分别被两对角线的共四个端点统计了一次,总个数除以 4 即可,输出 n 4 × ∑ i = 1 n − 3 i × ( n − 2 − i ) \large\frac{n}{4}\times\sum_{i=1}^{n-3}{i}\times{(n-2-i)} 4n×i=1n3i×(n2i)

注:对于运算过程中可能会超出 long long 类型范围,最终结果不会超的数据,考虑乘法(加法)除法(减法)同时进行,然而对于不能被整除的数据不可行,所以需预先判断是否能被除数整除,或者使用 double 类型。

洛谷CF1278B A+B

使 a a a , b b b 相等,即差为 0,设 k k k 为当前加数,让 a + k {a}+{k} a+k 不变,让 b + k b+k b+k 变为让 a − k a-k ak,考虑背包,枚举每个差是否可以取到,于是你就 TLE + MLE + RE + WA 了(范围)。

考虑贪心,令 a < b a<b a<b ,记 c = ∑ i = 1 n i c=\sum_{i=1}^{n}i c=i=1ni n n n 为满足 c ≥ b − a c \ge b-a cba的最小正整数,记 a ′ = a + c a'=a+c a=a+c,若 c − ( b − a ) c-(b-a) c(ba) 为偶数,则一定可以从 a ′ a' a 中取出 ( a ′ − b ) 2 \large\frac{(a'-b)}{2} 2(ab) 这个整数,将 a ′ a' a b b b 多出来的部分与 b b b 平分,枚举即可。

因数分解

计算 n n n 的标准因数分解式中 x x x 的指数。
f ( n , x ) = ∑ i ≥ 1 ∞ n x i \large f(n,x)=\sum_{i\ge1}^{\infty}\frac{n}{x^i} f(n,x)=i1xin,时间复杂度 O ( log ⁡ ( n ) ) O(\log(n)) O(log(n))

代码实现:

int f(int n,int x){
	int p=0;
	while(n){
		n/=x;
		p+=n;
	}
	return p;
}

龟速乘

a × b   m o d   p a\times b\bmod p a×bmodp
对于模数在 long long 范围内,原数 a , b a,b a,b 直接相乘导致溢出的考虑龟速乘。原理同快速幂相差不大。时间复杂度 O ( log ⁡ b ) O(\log b) O(logb)

代码实现:

ll smul(ll a,ll b,ll p){
	ll c=0;
	a=(a%p+p)%p,b=(b%p+p)%p;
	for(;b;b>>=1){
		if(b&1)c=(c+a)%p;
		a=(a+a)%p;
	}
	return c;
}

快速乘

a × b   m o d   c → a b − ⌊ a b c ⌋ × c a\times b\bmod c\rightarrow ab-\lfloor \frac{ab}{c} \rfloor\times c a×bmodcabcab×c
利用自然溢出特性,仅适用于某些测评机。时间复杂度 O ( 1 ) O(1) O(1)

代码实现:

ll qmul(ll a,ll b,ll p){
	ll ans=a*b-(ll)((double)a*b/p+0.5)*p;
}

拓展欧几里得

a x ≡ c ( m o d b ) → a x + b y = c ax\equiv c\pmod b\rightarrow ax+by=c axc(modb)ax+by=c
代码实现:

void exgcd(ll a,ll b,ll &x,ll &y){
	if(!b)x=1,y=0;
	else exgcd(b,a%b,y,x),y-=a/b*x;
}
ll exgcd(ll a,ll b,ll &x,ll &y){//顺便求 gcd
	if(!b){x=1,y=0;return a;}
	else {ll c=exgcd(b,a%b,y,x);y-=a/b*x;return c;}
}

ll x,y,d=c,g=exgcd(a,b,x,y),m=b/g;
if(d%g)continue;//无解
ll x=(x*(d/g)%m+m)%m;//最小非负整数解

拓展中国剩余定理

{ x ≡ a 1 ( m o d b 1 ) x ≡ a 1 ( m o d b 1 ) x ≡ a 2 ( m o d b 2 )   ⋯ x ≡ a k ( m o d b k ) \begin{cases}x \equiv a_1\pmod {b_1}\\ x \equiv a_1\pmod {b_1}\\ x \equiv a_2\pmod {b_2}\\ \space\cdots\\ x \equiv a_k\pmod {b_k}\\\end{cases} xa1(modb1)xa1(modb1)xa2(modb2) xak(modbk)
代码实现:

ll a[maxn],b[maxn];
ll excrt(){//龟速乘版本
	ll ca=a[1],cb=b[1];
	for(int i=2;i<=n;++i){
		ll x,y,d=a[i]-ca,g=exgcd(cb,b[i],x,y);
		if(d%g)return -1;
		ll m1=b[i]/g,m2=cb*m1;
		x=(smul(x,d/g,m1)+m1)%m1;
		ca=(ca+smul(x,cb,m2)+m2)%m2;
		cb=m2;
	}
	return ca;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值