最大素数

1625: 【例 1】反素数 Antiprime

橙三吉。 提交于 2019-11-28 02:50:36
1625: 【例 1】反素数 Antiprime 【题目描述】 原题来自:POI 2001 如果一个大于等于 1 的正整数 n ,满足所有小于 n 且大于等于 1 的所有正整数的约数个数都小于 n 的约数个数,则 n 是一个反素数。譬如: 1 , 2 , 4 , 6 , 12 , 24 ,它们都是反素数。 请你计算不大于 n 的最大反素数。 【输入】 一行一个正整数 n 。 【输出】 只包含一个整数,即不大于 n 的最大反素数。 【输入样例】 1000 【输出样例】 840 【提示】 数据范围与提示: 对于 10% 的数据, 1 ≤ n ≤ 10 3 ; 对于 40% 的数据, 1 ≤ n ≤ 10 6 ; 对于 100% 的数据, 1 ≤ n ≤ 2 × 10 9 。 这道题是一本通的例题,虽然代码很短但是注释过于简单不变理解,洛谷大佬的题解太长又不想看。。 #include<bits/stdc++.h> using namespace std; #define ll long long int a[20]={0,2,3,5,7,11,13,17,19,23,29}; ll n,s,s1; void dfs(ll x,ll y,ll b,ll z) { if(x==11) return ; ll i,k=1; for(i=1;i<=b;i++) { k*=a[x]; if(y*k

素数 筛 理解

浪子不回头ぞ 提交于 2019-11-28 01:59:30
埃拉托斯特尼筛法的时间复杂度是O(n*lglgn) bool vis[maxn];//能否被 素数合成 //int prime[maxn], cnt = 0; void Prime(int num) { for (int i = 2; i < maxn; i++) { if (vis[i]) continue; // prime[++cnt] = i; for (int j = 2; j < maxn; j += i) { vis[j] = true; } } } 线性筛 接近O(n) bool vis[maxn];//能否被 素数合成 int prime[maxn], cnt = 0; void Prime(int num) { for (int i = 2; i < maxn; i++) { if (!vis[i]) prime[++cnt] = i; for (int j = 1; j <= cnt && i * prime[j] < maxn; j++) { vis[i * prime[j]] = true; if (i % prime[j] == 0) break; /* 这里的意义相当重要 埃筛法比线性筛法久的原因在于在去除 素数可以组成的合数 的过程 一个合数可能由多个 不同 质因数的次方 相乘 而一个合数 可以看作为 一个最小素数与另一个数的乘积 i 无论是作为一个

数论——HDU - 2136

爷,独闯天下 提交于 2019-11-27 07:58:05
题目链接 题目含义 找出一个数最大素数因子的序号 题目分析 我们可以在筛素数的同时,用这个素数标记它的倍数,说明这些倍数一定有它这个素数因子 这样筛一遍下来,一个数大的素数因子就会覆盖它小的素数因子 题目代码 #include<iostream> #include<stdio.h> #include<string.h> #include<vector> using namespace std; typedef long long LL; const int maxn=1000007; int prime[maxn],num[maxn]; bool check[maxn]; int cnt=0; void Prime(){ num[1]=0; for(int i=2;i<maxn;i++) if(!check[i]){ prime[cnt++]=i; for(int j=1;j*i<maxn;j++){ check[j*i]=true; num[j*i]=cnt; } } } int main(){ Prime(); int n; while(~scanf("%d",&n)){ printf("%d\n",num[n]); } return 0; } 来源: https://www.cnblogs.com/helman/p/11352527.html

【世界数学难题】素数判定与大数因子分解问题(下)

大兔子大兔子 提交于 2019-11-26 22:46:55
6.一种概率算法   缪内的结果虽然很好,但它毕竟是依赖于一个悬而未决的假设.因而在实用中,它是不能被采用的.故我们回到勒默的结果,看看从这个结果还能引伸出什么方法来.   勒默的结果说,若n是合数,则存在a,满足(a,n)=1使样的a至少有多少.     n是合数时,由勒默的结果定理2.12,Mn是Un的真子群,即Mn≠Un,因而Mn在Un中的指标至少是2,即(Un∶Mn)≥2.故Mn中的元素个数至多是Un中元素个数的一半,即Un中不在Mn中的元素个数至少     (modn).   证明 对1到n之间的数a,若(a,n)≠1,则显然a不满足      这个推论可以产生一种作“素性判别”的概率算法:   对任何输入n,从1到n之间随机地抽取k个数a1,a2,…,ak 是否成立,若有某个ai使此同余式不成立,则断言n是合数;若对a1,…,ak,同余式都成立,则断言n是素数.   在这个算法中,ai的选取是随机的,而且结论(断言)正确性不是完全确定的,故此算法叫概率算法.在这个概率算法中,当得到断言说输入n是合数时,由定理2.11,结论是正确的;当得到断言说输入是素数时,没有什么定理可以确保结论是正确的.也就是说,此算法在执行完毕后,可能将一个事实上是合数的输入断言为是素数了.但是,由以上定理2.15的推论,这种出错的概率是很小的.因为,若n事实上是合     乎为零(但不是零!)

100以内的质数

…衆ロ難τιáo~ 提交于 2019-11-26 19:43:24
  质数(prime number)又称 素数 ,有无限个。质数定义为在大于1的自然数中,除了1和它本身以外不再有其他 因数 ,这样的数称为质数。   求解一个算法,我们首先要知道它的数学含义.依据这个原则,首先我们要知道什么是素数.; 素数是这样的整数,它除了表示为它自己和1的乘积以外,无论他表示为任何两个整数的乘积。 找素数的方法多种多样。 1 #include <stdio.h> 2 #include<math.h> 3 4 void main(){ 5 int i,j; 6 for (i=2;i<100;i++){ 7 int flag=0; 8 for (j=2;j<sqrt(i);j++){//从2到sqrt(i)进行判断 9 if(i%j==0) flag=1;//若存在其他因子,flag=1 10 } 11 if(flag==0) printf("%d-",i);//flag==0则表示不存在除了1和本身的其他因子。可以输出。 12 } 13 }   1:是从2开始用“是则留下,不是则去掉”的方法把所有的数列出来(一直列到你不想再往下列为止,比方说,一直列到10,000)。第一个数是2,它是一个素数,所以应当把它留下来,然后继续往下数,每隔一个数删去一个数,这样就能把所有能被2整除、因而不是素数的数都去掉。在留下的最小的数当中,排在2后面的是3,这是第二个素数

数论

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-26 19:35:43
以下仅供个人整合资料使用,非本人原创 倍数 对于自然数 a, b,如果存在自然数 k,使得 ka = b,那么 b是 a 的倍数,称 a 整除 b,b 能被 a 整除,记做 a|b 一个数有无穷多个倍数 所有数都是自身和 1 的倍数 倍数具有传递性 在 [1, n] 范围内的 x 的倍数有 ⌊nx⌋个 约数 对于自然数 a, b,如果 b 是 a 的倍数,那么 a 是 b 的约数,又称因数 所有数的约数都包含自身和(或)1 一个自然数只有有限个约数,约数的个数通常记为 d(n) 打个表看看 n 1 2 3 4 5 6 7 8 9 10 d(n) 1 2 2 3 2 4 2 4 3 4 打表 int d[MAXN]; // 计算出 [1, n] 中每个数的约数个数 // 复杂度 O(n log n) void calc_divisors(int n) { for (int i = 1; i <= n; ++i) { // 枚举 i 的所有倍数 for (int j = i; j <= n; j += i) { d[j]++; } } } 素数与合数 如果一个数的约数只有两个(1 和自身),那么称它为素数(或者质数) 如果一个数有非平凡(除了 1 和自身以外)的约数,就称它为合数 1 既不是素数也不是合数! 素性判定: // 判断一个数是否为素数 bool is_prime(int x

P3951小凯的疑惑

时光毁灭记忆、已成空白 提交于 2019-11-26 18:02:25
这是2017年提高组的第一题,是一个小学奥数题?听说很多大佬爆零了,我AC了,,, 这个题首先给出两个素数,问取任意个这两个素数之和不可以达到的最大的数是多少?拿到这个题首先很蒙,于是试了试样例,并没有得到什么启发,于是就构思代码,想双层for循环这两个数的个数,但怎样最大呢?然后再次去分析数据。eg.7&3=11,2&5=3,3$4=5。突然间,发现这些值都是 a*b-(a+b)。 但是看数据范围,发现1*10^9-->1*10^18,所以一定要开 long long. 1.拿到这种“奥数”,一定要分析透彻数据,寻找公式,再思考原理去验证公式正确性,前提是数据必须算对 2.注意对数据范围进行运算 代码 #include<iostream> #include<cstdio> using namespace std; int main(){ long long a,b; cin>>a>>b; cout<<(a*b)-(a+b); return 0; } 是的,这个题的代码可能是历史上最简单的了。 来源: https://www.cnblogs.com/china-mjr/p/11330005.html