死了吗小枫~ 死了吗小枫~ 死|

GCSG01

园龄:1年3个月粉丝:2关注:20

简单数学与位运算

本文经 @sLMxf 转载:

整除和余数

  • 以下 xya 均为整数。
  • 存在整数 k,使得 x=ky,则有 y|xy 整除 x ),若 y>0 则称 xy 的倍数,yx 的因数。
  • 如果 x=ky+a,则称 ax/y 的余数,写作 a=x,当 a=0 当且仅当 y|x

同余

  • 如果 x%z=y%z ,则我们称 xyz 同余,记作 xy(modz)
  • 如果 (xy)z 的倍数,那么 xyz 同余。
    证明:记 x=cz+a,y=dz+b0a,b<z)xy=(cd)z+ab,由于 (xy)z 的倍数,所以 (ab)|z,而 0a,b<z,故易得 a=b,所以同余。
  • 如果且 ab(modm),cd(modm) ,则 a±cb±d(modz),证明雷同上面。
  • 乘号同理,但是除法不行。
  • 如果 ab(modm),则 anbn(modm)

取余运算

  • (a+b)%m=(a%m+b%m)%m
  • (ab)%m=(a%mb%m+m)%m
  • (a×b)%m=(a%m×b%m)
  • ab%m=(a%m)b%m
  • 这些等式可以用在需要取模,且数字会经过多次运算的题目中,防止中间变量超出数据范围。

质数

  • 只能被 1 和自己整除的数,称为质数
  • N 充分大时,1 ~ N 范围内的质数个数约为 N/logN
  • 在某个正整数 N 附近找质数,能够在 logN 期望时间内发现一个质数。
  • 如何判断一个整数 n 是否为质数:2n 试除,发现约数则不是质数,复杂度 O(n)
  • an/a 中至少有 1 个数不超过 n,完全平方数的情况 2 个数都等于 n

筛法(埃式筛)

  • 在学数组的时候,我们学过一个判断 1 ~ n 是否为质数的方法:从小到大,依次将每个质数的倍数删去(若遍历到一个数时,其没有被删去,则可知这个数是质数),最终留下的全是质数。
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;
}
  • ji×i 开始是因为 2×i3×i 等数字在 i=2,i=3 的时候已经被枚举过了。
  • 时间复杂度 O(nloglogn)

筛法(线性筛)

  • 数字 30 还是被筛了多次(3×102×155×6)。如果能保证每个合数都只被它的最小质因数筛掉就好了。
    比如 2 筛掉 4681012
    比如 3 筛掉 91521
    比如 5 筛掉 253555
  • 我们记求解到 i 的质数数组为 p,则对于每个数字 i,我们希望 i×p1i×p2 等数字都被筛掉。这样一定是能筛干净的,因为合数 a= 某个质数 b× 另一个数 c,我们一定能在枚举到每个合数前,枚举到比它小的 c,这样当 pj=b 时,a 就被干掉了。
  • 每个合数还是没有只被它的最小质因数筛。
  • 60,被 3×20干掉一次,被 15×4干掉一次。
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] |i,且 i 的所有质因数肯定都比 p[j] 大,因为如果有小的那 j 早就被停在前面了。故被筛掉的 i× p[k] 的最小质因数肯定是 p[k]
  • 同理可证,设有比 p[j] 大的质数 p[l] ,则删 p[l] ×i 一定会出现重复,因为假设 p[l] ×i/ p[j]x,当 i 枚举到 x 时候,x× p[j] 又会把这个数字筛一次。
  • 时间复杂度 O(n)
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仅能以唯一方式分解为有限质数的乘积:
  • n=p1e1×p2e2×ptet
  • 其中 pi 是质数,ei 是正整数,且 iei都是 logn 数量级别的。
  • 根据乘法定理易得 n 的因数个数为 (e1+1)×(e2+1)××(et+1)
  • 还能求出 n 的因数和为 (p1e1+p1e11+p1e12++p1)(p2e2+p2e21+p2e22++p2)(pnen+pnen1+pnen2++pn)
  • 算术基本定理是一条非常基本和重要的定理,它把对自然数的研究转化为对其最基本的元素——质数的研究。

质因数分解

  • 2n 都试一下,如果能除的尽 n 就用 while 除,要把次数记下来。
  • 最后剩下的数字如果步数 1 ,一定是最大的质因数。

gcd 和 lcm

  • m|xm|y ,称为 mxy 的公因数。最大的 m 叫最大公因数 (gcd)
  • x|ny|n,称为 nxy 的公倍数。最小的 n 叫最小公倍数 (lcm)
  • d=gcd(x,y),那么 d 的唯一分解中任意质数的指数 eix,y 的唯一分解中此质数指数的 min
  • e=lcm(x,y),那么 e 的唯一分解中任意质数的指数 eix,y 的唯一分解中此质数指数的 max
  • 比如 gcd(240,180)=60,分解质因数如下,发现 60 的质因数中 23的指数取得是上面两个数分解 23 的指数的最小值
    • 180=22×32×51
    • 240=24×31×51
    • 60=22×31×51
  • lcm 则是取最大值,易得 gcd(x,y)×lcm(x,y)=x×y

位运算

  • & 运算:二进制下进行二元运算,每一位全 11 ,反之为 0。性质:a&bmin(a,b).
  • | 运算:二进制下进行二元运算,每一位有 1 则1,反之为 0。性质:a|bmax(a,b).
  • ^ 运算:二进制下进行二元运算,每一位不同则 1,反之为 0。性质是自己就是自己的逆运算。
  • 运算:一元运算符(和符号一样),让二进制下的每一位都取反(包括符号位)。
  • <<运算:进制下把每一位向左平移,低位用 0 补足。
  • 1<<n 等价于 2nx<<n 等价于 x×2n
  • >>运算:进制下把每一位向右平移,低位越界则舍弃。
  • n>>1=n2
  • 注意位运算,搞不清就打括号!

一些操作

  • lowbit(n) 表示表示二进制下 n 的最低的一个 1 它后面的 0 组成的数.
  • lowbit(n)=(n) and (n),原理自己想。
  • popcount(n) 表示二进制 n 有多少位是 1,原理自己想。
int ans=0;
while(n)
{
    ans++;
    n-=lowbit(n);
}
return ans;
posted @   GCSG01  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
漂浮磁力线/鼠标吸铁石特效
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起