简单数学与位运算
本文经 @sLMxf 转载:
整除和余数
- 以下 均为整数。
- 存在整数 ,使得 ,则有 ( 整除 ),若 则称 是 的倍数, 是 的因数。
- 如果 ,则称 为 的余数,写作 ,当 当且仅当 。
同余
- 如果 ,则我们称 和 对 同余,记作 。
- 如果 是 的倍数,那么 和 对 同余。
证明:记 则 ,由于 是 的倍数,所以 ,而 ,故易得 ,所以同余。 - 如果且 ,则 ,证明雷同上面。
- 乘号同理,但是除法不行。
- 如果 ,则 。
取余运算
- 这些等式可以用在需要取模,且数字会经过多次运算的题目中,防止中间变量超出数据范围。
质数
- 只能被 和自己整除的数,称为质数
- 当 充分大时, ~ 范围内的质数个数约为 。
- 在某个正整数 附近找质数,能够在 期望时间内发现一个质数。
- 如何判断一个整数 是否为质数: 到 试除,发现约数则不是质数,复杂度
- 和 中至少有 个数不超过 ,完全平方数的情况 个数都等于 。
筛法(埃式筛)
- 在学数组的时候,我们学过一个判断 ~ 是否为质数的方法:从小到大,依次将每个质数的倍数删去(若遍历到一个数时,其没有被删去,则可知这个数是质数),最终留下的全是质数。
f[1]=false;
for(int i=2;i<=n;i++) f[i]=true;
for(int i=2;i<=n;i++)
{
if(f[i]==true)
for(long long j=(long long)i*i;j<=n;j+=i)
f[j]=false;
}
- 从 开始是因为 、 等数字在 的时候已经被枚举过了。
- 时间复杂度 。
筛法(线性筛)
- 数字 还是被筛了多次()。如果能保证每个合数都只被它的最小质因数筛掉就好了。
比如 筛掉
比如 筛掉
比如 筛掉 - 我们记求解到 的质数数组为 ,则对于每个数字 ,我们希望 等数字都被筛掉。这样一定是能筛干净的,因为合数 某个质数 另一个数 ,我们一定能在枚举到每个合数前,枚举到比它小的 ,这样当 时, 就被干掉了。
- 每个合数还是没有只被它的最小质因数筛。
- 如 ,被 干掉一次,被 干掉一次。
f[1]=false;
for(int i=2;i<=n;i++) f[i]=true;
for(int i=2;i<=n;i++)
{
if(f[i]==true) p[cnt++]=i;
for(int j=1;j<=cnt&&i*p[j]<=n;j++)
f[p[j]*i]=false;
}
- 内层循环加上一句
if(i%p[j]==0)break;
即可。为什么? - 此时,比
p[j]
小的质数p[k]
不满足p[k]
,且 的所有质因数肯定都比p[j]
大,因为如果有小的那 早就被停在前面了。故被筛掉的p[k]
的最小质因数肯定是p[k]
。 - 同理可证,设有比
p[j]
大的质数p[l]
,则删p[l]
一定会出现重复,因为假设p[l]
p[j]
是 ,当 枚举到 时候,p[j]
又会把这个数字筛一次。 - 时间复杂度 。
f[1]=false;
for(int i=2;i<=n;i++) f[i]=true;
for(int i=2;i<=n;i++)
{
if(f[i]==true) p[cnt++]=i;
for(int j=1;j<=cnt&&i*p[j]<=n;j++)
{
f[p[j]*i]=false;
if(i%p[j]==0)break;
}
}
唯一分解定理
- 任何大于1的正整数n仅能以唯一方式分解为有限质数的乘积:
- 其中 是质数, 是正整数,且 和 都是 数量级别的。
- 根据乘法定理易得 的因数个数为 。
- 还能求出 的因数和为 。
- 算术基本定理是一条非常基本和重要的定理,它把对自然数的研究转化为对其最基本的元素——质数的研究。
质因数分解
- 到 都试一下,如果能除的尽 就用
while
除,要把次数记下来。 - 最后剩下的数字如果步数 ,一定是最大的质因数。
gcd 和 lcm
- 若 且 ,称为 为 和 的公因数。最大的 叫最大公因数 。
- 若 且 ,称为 为 和 的公倍数。最小的 叫最小公倍数 。
- 设 ,那么 的唯一分解中任意质数的指数 为 的唯一分解中此质数指数的 。
- 设 ,那么 的唯一分解中任意质数的指数 为 的唯一分解中此质数指数的 。
- 比如 ,分解质因数如下,发现 的质因数中 和的指数取得是上面两个数分解 和 的指数的最小值
- 则是取最大值,易得
位运算
- 运算:二进制下进行二元运算,每一位全 则 ,反之为 。性质:.
- 运算:二进制下进行二元运算,每一位有 则1,反之为 。性质:.
- ^ 运算:二进制下进行二元运算,每一位不同则 ,反之为 。性质是自己就是自己的逆运算。
- 运算:一元运算符(和符号一样),让二进制下的每一位都取反(包括符号位)。
- 运算:进制下把每一位向左平移,低位用 补足。
- 等价于 , 等价于
- 运算:进制下把每一位向右平移,低位越界则舍弃。
- 注意位运算,搞不清就打括号!
一些操作
- 表示表示二进制下 的最低的一个 它后面的 组成的数.
- ,原理自己想。
- 表示二进制 有多少位是 ,原理自己想。
int ans=0;
while(n)
{
ans++;
n-=lowbit(n);
}
return ans;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗