zoukankan      html  css  js  c++  java
  • 要命的逆元

    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
      整除?

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

    素数

    时间复杂度

    [{Osqrt 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×4cdots×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{ egin{array}{c} {(a/b) mod p ot= frac{a mod p}{b mod p}}\ {(a/b) mod p = (a mod p)*(b^{-1} mod p)} end{array} ight. ]


    推理过程

    • 我们有: 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,转载请声明出处

  • 相关阅读:
    Java后端面试题大汇总,冲刺金三银四
    面试官:小伙子,Mybatis的本质和原理说一下
    面试官问:大量的 TIME_WAIT 状态 TCP 连接,对业务有什么影响?怎么处理?
    便捷搭建 Zookeeper 服务器的方法,好用,收藏~
    10 个冷门但又非常实用的 Docker 使用技巧
    mitmproxy 抓包工具(1)
    基于alpine创建Scrapy镜像
    强大的输入框-应用快速启动uTools
    Interceptor、Filter、Servlet的区别
    利用三层判断sql数据库中编码是否已经存在(个人拙作,不喜勿喷)
  • 原文地址:https://www.cnblogs.com/lToZvTe/p/13816203.html
Copyright © 2011-2022 走看看