![](https://img-blog.csdnimg.cn/20201014180756724.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数论
FightingForFinal
这个作者很懒,什么都没留下…
展开
-
最大公约数最简洁的方法
如果 a > b,gcd ( a , b ) = gcd ( a - b , b ) 如果 a = b,gcd ( a , b ) = a = b如果 a = 0,gcd ( a , b ) = b 如果 b = 0,gcd ( a , b ) = a 一般情况不考虑一个数和0的最大公约数,如要考虑加特判即可此方法很简洁,满足一般需求,但不适应于大数,Stein算法是更好的算法,大数也不在话下原创 2015-09-17 15:43:59 · 458 阅读 · 0 评论 -
C/C++基本数据类型大小及表示范围
1原创 2015-11-03 21:09:03 · 743 阅读 · 0 评论 -
整除
整除规则第四条(4):最后两位能被4整除的数,这个数就能被4整除。 整除规则第七条(7):把个位数字截去,再从余下的数中,减去个位数的2倍,差是7的倍数,则原数能被7整除。 整除规则第八条(8):最后三位能被8整除的数,这个数就能被8整除。 整除规则第九条(9):每一位上数字之和能被9整除,那么这个数就能被9整除。 整除规则第十一条(11):将一个数从右往左数,将奇数位上的数原创 2016-05-24 13:34:47 · 1155 阅读 · 0 评论 -
Manacher算法O(n)求最长回文
证明见此处 51nod1089最长回文子串 V2(Manacher算法)#include<cstdio>#include<cmath>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#include<string>#include<sstream>#include<vector>#inc原创 2016-05-24 15:52:53 · 247 阅读 · 0 评论 -
大数组合数取模(逆元+打表)
将阶乘O(n)打表之后C(n,m)便可O(1)求出,除法取模用逆元解决 hdu5698瞬间移动#include<bits/stdc++.h>using namespace std;const int maxn=200000;const int p=1000000007;int f[maxn+10];void init(){//阶乘 f[0]=1; for(int i=1;i原创 2016-05-23 11:04:43 · 2779 阅读 · 1 评论 -
乘法逆元
满足x与y的乘积对z取模等于1时,x和y对于模数z来说互为逆元 即 x*y=1(mod z) 为什么要求逆元呢? 比如求 (b/a)mod p 时,如果b大到不可直接求出,我们可以先求出在模数p下与a互为逆元的数x,那么 (b/a)mod p 转化成 (b*x)mod p证明略。。。求逆元: 方法一(a和p互质,扩展欧几里算法): :a * x + p * y = gcd( a , p )原创 2016-03-02 22:19:47 · 1129 阅读 · 0 评论 -
生成随机数
调用一次srand(time(NULL));初始化“随机数种子”,然后使用rand()即可,产生的随机数在闭区间 [0 , RAND_MAX] ,RAND_MAX至少为32767(2^15-1),是个const量,可以直接打印出来。#include<bits/stdc++.h>using namespace std;int main(){ cout<<RAND_MAX<<endl;原创 2016-05-25 14:12:40 · 218 阅读 · 0 评论 -
快速幂
采用二分的方法,复杂度O(logn) 取模的话可以直接加在函数里int fast(int a,int x){//计算a的x次方 if(x==0)return 1; if(x%2)return a*fast(a,x-1); int tmp=fast(a,x/2); return tmp*tmp;}如果计算 (a^x)%c ,其中a,x,c数据最大为 2^64-1 的原创 2016-03-01 22:17:19 · 306 阅读 · 0 评论 -
求解a^b % m
a^b % m==a^(b % phi(m) + phi(m) )%m ,证明见此处 如果m是质数(那么phi(m)=m-1)且b非常大,求b的过程中就需要取模,那么这个公式就有了意义原创 2016-04-23 11:20:32 · 506 阅读 · 0 评论 -
扩展欧几里得算法
int x,y;void extend(int a,int b){ if(b==0){ x=1; y=0; return; } extend(b,a%b); int t=x; x=y; y=t-a/b*y;}原创 2016-03-02 21:55:28 · 282 阅读 · 0 评论 -
逆序数 归并排序求法
在将两个相邻的区间合并的时候统计逆序数当交换两个数的时候不会改变除了这两个数之外的数的逆序数,同理合并两个区间时不会改变除这两个区间外的数的逆序数。比如两个相邻的有序序列区间s1={3, 5, 6},s2={1, 4, 7}, 当第一个序列某个元素a[i]小于等于第二个序列的a[j]时逆序数为0,当a[i]>a[j]时,s1中a[i]后面的所有元素均大于等于a[i],也就大于a[j],所以逆序数就原创 2016-02-28 16:02:09 · 759 阅读 · 0 评论 -
中国剩余定理
int china(){ int M=1; for(int i=1;i<=n;i++){ M*=m[i]; } int ans=0; for(int i=1;i<=n;i++){ extend(M/m[i],m[i]);//扩展欧几里得算法求逆元 ans=(ans+a[i]*M/m[i]*x)%M; }原创 2016-03-04 09:26:58 · 249 阅读 · 0 评论 -
Stein算法求最大公约数
求最大公约数最快捷的方法,求大数的最大公约数也是轻而易举#include<iostream>using namespace std;int gcd(int a,int b){ if(a<b)swap(a,b); //保证a>=b if(a==b||b==0)return a; //相等或者有0的就结束 if(a%2==0&&b%2==0)return 2*gc原创 2015-09-17 15:42:45 · 421 阅读 · 0 评论 -
费波拉契通项公式变形
HDU1568Fibonacci费波拉契通项公式: 以10为底取对数: 这一项趋近于0,且n越大越趋近于0所以取 即可,然后应该返回吗?不是的!这样得到的数根本没变,还是非常大,我们取log10(F(n))的小数部分即可,因为: 设一个数x的整数部分为a,小数部分为b,则, 决定小数点的位置, 才决定了这个数的每一位上的数字是多少, 比如: 需要前多少位只要移动 的小数点位置(反复乘原创 2015-09-17 15:46:54 · 670 阅读 · 0 评论 -
HDU4135 容斥原理+质因子+DFS
HDU4135Co-prime 题意:求区间[A , B]内与N互质的数的个数分析: 将问题转换一下,用[1 , B]内与N互质的数的个数减去[1 , A-1]内与N互质的数的个数,现在就变成要求[1 , C]内与N互质的数的个数,这样不好求,但是求与N互质的数的个数(设为num)很简单,那么最后答案就是C-num 如何求与N不互质的数的个数: 比如C=12,N=30 第一步:求出N的所有原创 2015-10-27 18:31:09 · 410 阅读 · 0 评论 -
组合数
根据这个公式求,不仅慢,而且中间值有阶乘会溢出,不采用因此我们可以取对数来解决数太大的问题: #include<cmath>#include<iostream>using namespace std;double C(int n,int m){ double lg=0; for(int i=m+1;i<=n;i++) lg+=log10(i); for原创 2015-09-17 15:47:52 · 393 阅读 · 0 评论 -
素数筛法
素数筛法能很快的求出N以内的所有素数 原理:若一个数不是素数,则必存在一个小于它的素数为它的因子,所以在获得一个素数时,将它的所有倍数都标记为非素数,这样当遍历到一个数时,如果它没有被任何小于它的素数标记为非素数,那么它就一定是素数方法一:#define N 1000000int a[N];//素数标记为0,非素数标记为1int p[N];int cnt;void Init(){原创 2015-09-17 15:46:19 · 531 阅读 · 0 评论 -
求一个整数的质因数
适用于N的个数不是很多但是N又特别大(10^9)的情况,速度很快#include<iostream>using namespace std;int cnt;int a[1000];void Factor(int N){ cnt=0; for(int i=2;i*i<=N;i++){ if(N%i==0)a[++cnt]=i; while(N%i=原创 2015-10-27 16:19:49 · 533 阅读 · 0 评论 -
一次求多个整数的质因数
原理同素数筛法 的方法一,可以一次求[1,N]内所有整数的质因子(N不能太大,10^5左右)#include<iostream>#include<cstring>#include<vector>using namespace std;#define N 100000int vis[N+10];vector<int>a[N+10];void Init(){ for(int i=0;原创 2015-10-27 17:39:56 · 341 阅读 · 0 评论 -
欧拉函数
#define N 100001int e[N];void Init(){ for(int i=1;i<=N;i++)e[i]=i; for(int i=2;i<=N;i+=2)e[i]/=2; for(int i=3;i<=N;i+=2) if(e[i]==i){ for(int j=i;j<=N;j+=i)原创 2015-12-28 19:06:54 · 265 阅读 · 0 评论 -
斐波拉契快速求法:矩阵快速幂
斐波拉契数:f0=0,f1=1,……..fn=f[n-1]+f[n-2] 用矩阵表示: 2*2的矩阵用结构体表示:struct node{ int a,b; int c,d;};2*2矩阵乘法:node mult(node x,node y){ return {x.a*y.a+x.b*y.c,x.a*y.b+x.b*y.d,x.c*y.a+x.d*y.c,x.c*y.b原创 2016-03-01 22:07:03 · 405 阅读 · 0 评论 -
Miller-Rabin素数判定O((logn)^2)
证明见《算法分析与设计——c++语言描述(第2版)》的第232页,写的很详细。 其中用到了快速幂来判定是否满足费马小定理,并且判定x*x%n==1的解是否只有x=1和x=n-1#include<bits/stdc++.h>using namespace std;int fast(int a,int n,int p){//就是个快速幂,true则必为合数,false则以高概率为素数 int原创 2016-07-03 21:43:01 · 501 阅读 · 0 评论