要命的逆元

Day 2 基础数论算法

from hzwer
by Zxsure

基础概念:

假设 m 和 n 是整数,且 m 不是 0,则 m 整除 n 指的是 n 是 m 的倍
数,即存在整数 k,使得 n = mk

\[{m \| n \longrightarrow n = km} \]

如果 m 整除 a - b,我们就说 a 与 b 模 m 同余并记

\[\ a\ ≡ \ b(mod \ m) \]

举个例子:
\(1 \ ≡\ 15\ (mod \ 7)\)

  • \(15\ mod\ 7 = \ 1\)
  • \(1\ mod\ 7 = \ 1\)

换句话说:\(a\)\(b\) 的余数相同


例题:

  1. 证明:如果一个数每一位加起来可以被 3 整除,那这个数就可以被 3
    整除?

\[\begin{align} abcd\ & =\ 1000a\ +\ 100b\ +\ 10c\ +\ d \\ & ≡a\ +b\ +c\ +d\ (mod\ 3) \\ & =999a\ +99b\ +9c \\ & ≡0(mod\ 3) \end{align} \]

素数

时间复杂度

\[{O\sqrt n} \]

for(2~(sqrt)n)
check(i % m == 0)

素数筛法

在数列中筛去 2 ,3 ,5,7,8,9的倍数;

时间复杂度:

\[{n\ log\ log n} \]


例题

  1. 分解质因数

  2. 假设素数是有限的,假设素数只有有限的n个,最大的一个素数是p。

    \[{q_{max}\ = (2×3×4\cdots×p)+1} \]

  3. 不能被所有的素数整除就找到更大的素数。


素数的唯一分解

若整数 N≥2,那么 N 一定可以唯一地表示为若干素数的乘积。
形如

  • \({N = p_1^r ×p_2^r× …×p_k^r(p_i 为素数 , r_i ≥ 0)}\)

最小公倍数

\[gcd(a,b)=1(a,b\ 互质) \]

\[gcd(a,b) = gcd(b ,a\ mod\ b) \]

return b = 0 ? a : gcd(b,a % b)

欧几里得算法

\({gcd(a,b)=gcd(b, a\ mod \ b)}\)

• 设 g = gcd(a, b),r = a mod b,我们可以知道 a = kg + r

• 再根据 g 的最大公因数的性质(也就是同时整除a和b)就可以知道 g 也整除 r。

• 同样的,我们也可以证明,g 是同时整除 b 和 r 的最大的整数,这样,这个等式就成立了。

逆元

\[X*X^{-1}=1(mod\ p) \]

条件 :解决同余意义下,无法进行除法的问题

推理:

\[\left\{ \begin{array}{c} {(a/b)\ mod\ p\not= \frac{a\ mod\ p}{b\ mod\ p}}\\ {(a/b)\ mod\ p\ = (a\ mod\ p)*(b^{-1}\ mod \ p)} \end{array} \right. \]


推理过程

  • 我们有: inv(x)⋅x≡1 (mod p), 又据费马小定理:x^(p-1) ≡ 1 (mod p)

  • 故有:inv(x)⋅x ≡ x^(p-1) (mod p) ,两边同时除以 x 有:

  • inv(x) ≡ x^(p-2) (mod p) ,这就是模质数意义下的逆元求法。

  • \(inv\) 表示逆元

结论

\[a^{-1}=a^{p-2} \]

快速幂

  1. 求快速幂 \(a^b\)

  2. 预处理 \({a^1\ a^2\ a^3\ \cdots\ a^{2n} }\),对b进行二进制拆分

  3. 如:\({a^{21}=a^{16}*a^{4}*a^{1}}\)


练习题

CF1209A.Paint the Numbers (900)

题面:

  • 给 n 个数 a1 ~ an。要求你把它们分成 k 组,使得每⼀组中的数,都能被这一组最小值整除。问 k 最小是多少?

  • n <= 100, ai <= 10000

思路 :

  1. 将序列排序,从头往后一次考虑最小数

  2. 贪心+模拟

  3. 以当前最小数去找到与其相关的倍数组成一组(贪)

  4. 贪⼼筛法,每次取没被筛掉的最小元素,筛掉它的倍数(PPT)

Code :


CF486A.Calculating Function (1100)

题面 :

  • 计算函数 f(n) = -1 + 2 - 3 + .. + ( - 1)^n * n

  • n <= 10^15

思路 :

  1. n 为奇数,答案是 -(n+1)/2

  2. n 为偶数,答案是 n / 2


CF492B.Vanya and Lanterns (1200)

题面 :

  • 一个长为 L 的街道(左端点是 0,右端点是 L)上有 n 个相同的灯,第 i 个灯放置的位置是 ai

  • 问灯的半径至少要是多少,才能使得整个街道都有灯光。

  • n <= 1000, L <= 10^9

思路:

  1. 暴力找到灯之间的距离一半最大值

  2. 再比较两边界的的灯的距离。

CF570B. Simple Game (1300)

题面:

  • 给 n,m,求⼀个数 a (1 ≤ a ≤ n),使得当 c 在 1 到 n 的整数中随机取值时, |c − a| < |c − m| 成立的概率最大。

  • n, m <= 10^9, m <= n

思路:

  1. 分 2m ≤ n 和 2m > n 讨论

CF546B.Soldier and Badges (1300)

题面 :

  • 给 n 个数,每次操作可以将一个数 +1,要使这 n 个数都不相同, 求至少要加多少?

  • n <= 3000

思路:

  1. 排序,挨个+1

401C.Team(1400)

题面:

  • 构造一个 01 序列,包含 n 个 0,m 个 1

  • 要求不存在连续 2 个 0,或 3 个 1

  • 无解输出 -1

  • 1 ≤ n, m ≤ 10^6

思路:

  1. 判断无解的情况下。

  2. 011和01进行构造

Code

/*
 	2020/10/3 20:59
 	CF401C Team
	by BZQ
*/
#include<iostream>
using namespace std;
int n,m;
int main(){
	cin >> n;
	cin >> m;
	if(m > n*2 + 2 || n > m+1) cout << -1;//判断无解的情况 
	else
	{
		if(m > n*2){         //此处将 m >= n 的情况和 m > 2n 的情况做个合并。                
			for(int i = 1;i <= m - n*2; i++)//先对 m > 2n 进行预处理,之后操作一样。
				cout << "1";
			m = 2 * n; //注意:在做完预处理后,现在的序列就相当于是一个满011和01的序列,所以更新m; 				
		}
	    if(m >= n){
			for(int i = 1;i <= m - n; i++) // 先贪大后贪小 
		 		cout << "011";
			for(int i = 1;i <= 2*n-m; i++)
		 		cout << "01";
		}
 		if(n > m){
			cout << "0"; // 回复思路 1 中的问题:以为无解的边界为 n > m+1 故要想此时的 n > m 成立,当且仅当 n = m + 1; 
			for(int i = 1;i <= m;i++)
			 	cout << "10";
		}
	}
	return 0;
} //感谢观看,

413C.Jeopardy!(1400)


题面:

  • 给 n 个关卡,每个关卡得分为 ai,有 m 次机会可以选择一个关卡通过后不得分,而将现有得分翻倍

  • 你可以安排关卡的通过顺序和策略,求最大得分

  • 1 ≤ n, m ≤ 100

思路:

  1. 将可以翻倍关卡放在后头,且按从一到n排序,依次贪心

POJ2689. Prime Distance


题面 :

  • 给定两个整数 L, R (1 ≤ L ≤ R ≤ 2^31, R-L ≤ 10^6),

  • 求闭区间[L, R] 中相邻两个素数的差最大是多少?

思路:

  1. 预处理\({\sqrt{2^{31}}}\);

  2. 暴力判断

  3. 使用筛法求出 [2,√R] 之间的所有素数,对于每个素数 p ,把[L,R] 中能被 p 整除的数标记,即标记 i × p(⌈L/p⌉ ≤ i ≤ ⌊R/p⌋)为合数。

  4. 将筛出的素数进行相邻两两比较,找出差最大的即可


235A.LCM Challenge (1600)


题面:

  • 在小于n 的数中找三个数 a, b, c

  • 最大化 lcm(a, b, c)

  • n <= 10^6

思路:

  1. 在接近 n 的数内找三个两两互质的,小范围暴力

NOIP2014. 解方程

题面:

已知多项式方程:

  • \(a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\)

  • 求这个方程在 [1,m][1,m] 内的整数解(nn 和 mm 均为正整数)。

思路:

  1. 暴力验证[1,m]内的整数?系数太大,取模!

  2. 方程的解不会超过n个

  3. 如果\(x=x_0\)的时候,在对$p $ 取模后方程不成立,那么原方程必然不成立

  4. 用比较小的质数验证一个,先排除大部分

以上思路来源PPT,本人无思路,因为不会

作者 @Zxsure,转载请声明出处

posted @ 2020-11-04 19:21  zxsoul  阅读(221)  评论(2编辑  收藏  举报