基础数学总结
2015-09-18 16:48
441 查看
1.最基础的辗转相除法 O(log max(a, b))
2.扩展欧几里得算法 O(log max(a, b))
3.素数筛选 近似O(n)
4.大区间素数筛选 近似O(n)
5.素数筛选和合数分解 O(sqrt(n))
// 复杂度O(log max(a,b)) int gcd(int a, int b){ if(b == 0) return a; return gcd(b, a%b); }
2.扩展欧几里得算法 O(log max(a, b))
/* 用于解决方程:ax + by = gcd(a, b) 事实上,一定存在整数对(x, y)使得上述方程成立 其返回值是gcd(a, b) x y 的一组解直接通过引用返回 这组解满足|x| <= b && |y| <= a */ int extgcd(int a, int b, int &x, int &y){ int d = a; if(b != 0){ d = extgcd(b, a%b, y, x); y -= (a / b) * x; } else{ x = 1; y = 0; } return d; }
3.素数筛选 近似O(n)
int prime[maxn]; // 第i个素数(从0开始计数) bool is_prime[maxn+1]; // is_prime[i]为true表示i是素数 int getprime(int n){ //返回值是n以内素数的个数 int p = 0; for(int i = 0; i <= n; i++) is_prime[i] = true; is_prime[0] = is_prime[1] = false; for(int i = 2; i <= n; i++){ if(is_prime[i]){ prime[p++] = i; for(int j = 2*i; j <= n; j += i) is_prime[j] = false; } } return p; }
4.大区间素数筛选 近似O(n)
/* 注意区间前闭后开 [a, b) */ typedef long long LL; bool is_prime[maxn]; // maxn = 所给区间 [a, b) 长度最大值 bool is_prime_small[max_sqr_B]; // 这里开的区间大小是 最大的右边界B的平方根sqrt(B); // 对区间[a, b)内的整数执行筛法。is_prime[i-a] = true 即 i是素数 void seg_sieve(long long a, long long b){ for(int i = 0; (long long)i*i < b; i++) is_prime_small[i] = true; for(int i = 0; i < b-a; i++) is_prime[i] = true; for(int i = 2; (long long)i*i < b; i++){ if(is_prime_small[i]){ for(int j = 2*i; (long long)j*j < b; j += i) is_prime_small[j] = false; for(long long j = max(2LL, (a+i-1)/i)*i; j < b; j += i) is_prime[j-a] = false; } } }
5.素数筛选和合数分解 O(sqrt(n))
/* prime[0]是素数的个数cnt prime[1~cnt]是所有的素数 is_prime[i] = true表示 i 是素数 fatcnt表示当前这个数 x 有几个质因子 factor[i][0] 表示第i个质因子是factor[i][0] 数值 factor[i][1] 表示第i个质因子有factor[i][1]个 数目 */ int prime[maxn+1]; int is_prime[maxn+1]; void getprime(){ memset(prime, 0, sizeof(prime)); for(int i = 2; i <= maxn; i++){ if(!prime[i]) prime[++prime[0]] = i; for(int j = 1; j <= prime[0] && prime[j] <= maxn/i; j++){ prime[prime[j]*i] = 1; if(i % prime[j] == 0) break; } } for(int i = 1; i <= prime[0]; i++){ is_prime[prime[i]] = 1; } } long long factor[100][2]; int fatcnt; int getfactors(long long x){ fatcnt = 0; long long tmp = x; for(int i = 1; prime[i] <= tmp/prime[i]; i++){ factor[fatcnt][1] = 0; if(tmp % prime[i] == 0){ factor[fatcnt][0] = prime[i]; while(tmp % prime[i] == 0){ factor[fatcnt][1]++; tmp /= prime[i]; } fatcnt++; } } if(tmp != 1){ factor[fatcnt][0] = tmp; factor[fatcnt++][1] = 1; } return fatcnt; }
相关文章推荐
- 企业级证书打包下载安装之后无法使用问题
- bootstrap学习教程
- 基础之JDBC(2015年9月18日)
- YII框架入门
- springJDBC实现查询
- Hibernate与 MyBatis的比较
- 【DOS批处理】函数定义和用法
- iOS 如何面试
- Ext之Grid
- 1px
- 汇编语言第二版-第一章
- 浅析多线程及用法(实例)
- 关于struts2中default-action-ref的一些问题及首页设置
- 耳机标准
- spring使用aop需要的jar包,和常见异常
- 运维进行时-数据分析
- iOS 进阶面试题-Block部分
- Jbrowse中的BigWig Tracks配置
- Windows2008 Server 常规设置及基本安全策略
- 算法导论 O(n)时间内反转单链表