首页 > 其他分享 >整除基本知识

整除基本知识

时间:2023-12-03 21:23:01浏览次数:26  
标签:约数 space int 质数 基本知识 Maxn 整除 ll

整除基本知识

性质

  • 若\(a|b\) 且 \(b|c\),则 \(a|c\)。
  • 若\(a|b\) 且 \(b|c\),则 对于任意的整数 \(x、y\),有 \(a|(bx +cy)\)
  • 对于整数 \(m\neq 0\),\(a|b \leftrightarrow b|a\)

寻找约数

暴力

for (int i = 1; i <= n; i++)
{
	if (x % i == 0) ans[++cnt] = i;
}

优化

约数肯定是成对出现的。

对于 \(120\)。

如 \(2,60\)

即如果 \(k\) 是 \(n\) 的约数,那么 \(\frac nk\) 也一定是 \(n\) 的约数。

不妨设 \(k\) 是较小的一个(为了优化枚举时间),那么显然。

\[k \leq \frac n k \]

\[k \leq \sqrt n \]

那么对 \(k\) 枚举,时间复杂度就降低到了 \(\operatorname O(\sqrt n)\)。

int find_divisors(int n, int a[])
{
	int cnt = 0;
    for (int k = 1; k * k <= n; k++)
    {
		if (n % k == 0)
        {
			a[++cnt] = k;
            if (k != n / k) a[++cnt] = n / k;
        }
    }
    return cnt;
}

数列中的倍数数

P2926 USACO08DEC Patting Heads S

从枚举倍数的角度思考:对于一个数 $ i $ 若它在原数组中出现了 $ c[i] $ 次,那么 $ i $ 这个数会对它的每一个倍数产生 $ c[i] $ 的贡献。这样就可以通过查询这样产生的贡献的总和来计算答案了,其时间复杂度为:

\[O(nlogn) \]

代码:

#include <bits/stdc++.h>
using namespace std;
const int Maxn=1000100;//数组大小
const int Bignumber=1000000;
int n,a[Maxn],c[Maxn],w[Maxn];//n个数,数列,数字统计容器,贡献值
int main() {
	scanf("%d",&n);//输入
	for(int i=1;i<=n;i++) {
		scanf("%d",&a[i]);//输入数列
		c[a[i]]++;
	}
	for(int i=1;i<=Bignumber;i++) 
		for(int j=i;j<=Bignumber;j+=i)
			w[j]+=c[i];//i这个数会对j产生c[i]的贡献
	for(int i=1;i<=n;i++) 
		printf("%d\n",w[a[i]]-1);//输出时要把a[i]对自己的贡献减去
	return 0;
}

快速求因子数

依靠两个结论

  • 一个正整数一定能分解为若干质数\(\space n\space\)次方的乘积。
  • 一个数的因子数等于该数分解为若干质数\(\space n\space\)次方的乘积后每个质数的次方数加一的乘积。

举个例子

\[120=2^3\times3\times5 \]

那么因子数则是\(\space (3+1)\times(1+1)\times(1+1)=16\)。

代码实现

ll getInShu(ll n)
{
    ll ans = 1;
	for (int i = 2; i * i <= n; i++)
	{
		if (n % i == 0)//质因数分解
		{
			ll cnt = 0;//即这个因数的次方
			while(n % i == 0)
			{
				++cnt;
				n /= i;
			}
			ans = (ans mod) * ((cnt + 1) mod);
			ans = ans mod;
		}
	}
	if (n != 1)//说明剩下最后一个质因数
	{
		ans *= 2;
	}
	return ans mod;
}

标签:约数,space,int,质数,基本知识,Maxn,整除,ll
From: https://www.cnblogs.com/kdlyh/p/17873308.html

相关文章

  • 计算0到1000所有能被2和3 整除的数之和
    #include<stdio.h> intmain(){ int i,sum=0; for(i=0;i<=1000;i++) {  if(i%(2*3)==0)  {    sum=sum+i;  }   } printf("%d",sum); return0;}......
  • 实训课 - wireshark和网络配置基本知识
    接上文:实训课-计算机网络技术基础笔记https://blog.51cto.com/youyeye/8363907WireShark的基本抓包使用安装wireshark先在虚拟机上安装wireshark(直接在本机上将exe文件复制,然后切换到虚拟机上粘贴)然后工具栏capture–optionsInterface是接口,然后旁边的将是网卡,有两个选项,选择in......
  • JVM学习记录(基本知识点)
    一、老生常谈,JVM的组成部分有哪些1.类加载器(作用:将字节码文件加载到内存中的运行时数据区)2.运行时数据区(由多个部分组成,也是我们最为普遍较为的区域,大体上讲就是运行程序,包括了程序运行的全生命周期)3.执行引擎(作用:将字节码翻译成底层系统命令交给CPU去执行)4.本地库接口(作用:字节码翻......
  • 【文档翻译】每个开发者都必须了解的关于Unicode和字符集的基本知识
    本文档译自joelonsoftware.com的文章"TheAbsoluteMinimumEverySoftwareDeveloperAbsolutely,PositivelyMustKnowAboutUnicodeandCharacterSets(NoExcuses!)",作者joel,原文参见此处概述-Overview你是否在某一个平凡的日子,思考过那个神秘的Content-Type标......
  • 0到1000中能被2和3整除的数的和
    #include<stdio.h>intmain(){  inti,n=0;  for(i=0;i<=1000;i++)  {    if(i%2==0&&i%3==0)      n=n+i;      }  printf("%d",n);  return0;}......
  • 数据结构图的基本知识题
    判断题1.在n个结点的无向图中,若边数大于n-1,则该图必是连通图。​ TF解释:以下两种说法是对的:在n个结点的无向图中,若该图是连通图,则其边数大于等于n-1,在n个结点的无向图中,若边数大于(n-2)(n-1)/2,则该图必是连通图就是说连通是比较强的条件......
  • 数据结构图的基本知识题
    判断题1.在n个结点的无向图中,若边数大于n-1,则该图必是连通图。​ TF解释:以下两种说法是对的:在n个结点的无向图中,若该图是连通图,则其边数大于等于n-1,在n个结点的无向图中,若边数大于(n-2)(n-1)/2,则该图必是连通图就是说连通是比较强的条件......
  • umich cv-6-1 循环神经网络基本知识
    这节课中介绍了循环神经网络的第一部分,主要介绍了循环神经网络的基本概念,vanilla循环网络架构,RNN的一些应用,vanilla架构的问题,更先进的rnn架构比如GRU和LSTM循环神经网络基本知识vanilla循环网络架构应用与理解vanilla架构的问题LSTMvanilla循环网络架构在之前的讨论......
  • yum源的基本知识
    一、yum源配置1.本地yum源配置内容[local]#仓库名称,自定义,担具有唯一性‘唯一性是说在yum.repos.d这个文件夹中只能有一个这个名字的yum仓库’name=local_centos#仓库描述,类似于仓库解释,描述信息自定义,不具备唯一性baseurl=file://绝对路径(repodata的上一级目录)enabled=1#软......
  • 整除分块
    证明数论分块板子求$\large\sum_{i=1}^n[n/i]$,其中$n\leq10^{10}$很明显,暴力求的复杂度是$O(n)$的,需要优化其中,例$n=10$时,$[10/4]=[10/5]$是有相等的值的不妨设第一个$[n/i]=x$的数为$l$则最后一个有$[n/i]=x$的数$\larger=[\frac{n}{[n/l]}]$理由如......