数学问题的解题方法(模板)
2016-03-25 22:58
204 查看
辗转相除法:
1.最大公约数
2.扩展欧几里德算法
ax+by=gcd(a,b)
有关素数的基础算法:
1.素数判定
2.埃氏筛法
3. 区间筛法
模运算
凸包:
模板来自 : -> 萌哒哒~毅哥
<<挑战程序设计竞赛>>读后感......
1.最大公约数
int gcd(int a,int b){ if(b==0) return a; return gcd(b,a%b); }
LL gcd(LL a, LL b) { return b == 0? a : gcd(b, a % b); } void ex_gcd(LL a, LL b, LL& d, LL& x, LL& y) { if(!b) { d = a; x = 1; y = 0; } else { ex_gcd(b, a % b, d, y, x); y -= x * (a/b); } }
2.扩展欧几里德算法
ax+by=gcd(a,b)
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; }
有关素数的基础算法:
1.素数判定
//素性测试 bool prime(int n){ for(int i=2; i*i<=n; i++){ if(n%i==0) return false; } return n!=1; //1是例外 } //约数枚举 vector<int> dis(int n){ vector<int> res; for(int i=1; i*i<=n; i++){ if(n%i==0){ res.push_back(i); if(i!=n/i) res.push_back(n/i); } } return res; } //整数分解 map<int,int> prime(int n){ for(int i=2; i*i<=n; i++){ while(n%i==0){ ++res[i]; n/=i; } } if(n!=1) res =1; return res; }
2.埃氏筛法
int prime[MAX_N]; //第i个素数 bool is_prime[MAX_N+1] //is_prime[i]为true表示i是素数 //返回n以内素数的个数 int solve(int 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[i]=false; } } return p; }
3. 区间筛法
typedef long long ll; bool is_prime[MAX_L]; bool is_prime_small[MAX_B]; //对区间[a,b)内的整数执行筛法.is_prime[i-a] = true -- i是素数 void segment_sieve(ll a,ll b){ for(int i=0; (ll)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; (ll)i*i<b; i++){ if(is_prime_small[i]){ for(int j=2*i; (ll)j*j<b; j+=i) is_prime_small[j]=false; //筛[2,根号b) for(ll j=max(2LL,(a+i-1)/i)*i; j<b; j+=i) is_prime[j-a]=false; //筛[a,b) } } }
模运算
LL qpow(LL x, LL k) { LL res = 1; while(k) { if(k & 1) res = res * x % MOD; x = x * x % MOD; k >>= 1; } return res; } LL inv(LL a, LL x) { return qpow(a, x - 2); }
凸包:
struct point { double x; double y; point (double x = 0, double y = 0):x(x), y(y) {} }; typedef point Vector;//向量 Vector operator + (Vector A, Vector B)//向量加法 { return Vector(A.x + B.x, A.y + B.y); } Vector operator - (Vector A, Vector B)//向量减法 { return Vector(A.x - B.x, A.y - B.y); } Vector operator * (Vector A, double p)//向量乘法 { return Vector(A.x * p, A.y * p); } Vector operator / (Vector A, double p)//向量除法 { return Vector(A.x / p, A.y / p); } int dcmp(double x)//精度控制 { if(fabs(x) < eps) return 0; else return x < 0? -1 : 1; } bool operator == (const point& a, const point& b)//判断点相等 { return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; } double Dot(Vector A, Vector B)//向量点积,A*B,垂直为0 { return A.x * B.x + A.y * B.y; } double Length(Vector A)//向量长度 { return sqrt(Dot(A, A)); } double Angle(Vector A, Vector B)//向量极角 { return acos(Dot(A, B) / Length(A) / Length(B)); } double Cross(Vector A, Vector B)//向量叉乘,AXB, 有向面积的两倍 { return A.x * B.y - A.y * B.x; } double Area2(point A, point B, point C)//两向量组成的四边形的有向面积 { return Cross(B - A, C - A); } Vector Rotate(Vector A, double rad)//向量A,逆时针旋转rad°, 极角形式 { return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad)); } Vector Normal(Vector A)//A will not 0 Vector!, 求单位向量 { double L = Length(A); return Vector(A.x / L, A.y / L); } Vector GetLineIntersection(point P, Vector v, point Q, Vector w)//求两向量的交点(不求具体坐标) { Vector u = P - Q; double t = Cross(w, u) / Cross(v, w); return P + v * t; } double DistanceToLine(point P, point A, point B)// 点到直线的距离 { Vector v1 = B - A, v2 = P - A; return fabs(Cross(v1, v2)) / Length(v1); } double DistanceToSegment(point P, point A, point B)//点到线段的距离 { if(A == B) return Length(P - A); Vector v2 = P - A, v3 = P - B, v1 = B - A; if(dcmp(Dot(v1, v2) < 0)) return Length(v2); else if(dcmp(Dot(v1, v3)) > 0) return Length(v3); else return fabs(Cross(v1, v2)) / Length(v1); } point GetLineProjection(point P, point A, point B)//求点在直线上的投影 { Vector v = B - A; return A + v * (Dot(v, P - A) / Dot(v, v)); } bool SegmentProperIntersection(point a1, point a2, point b1, point b2)//两线段是否相交 { double c1 = Cross(a2 - a1, b1 - a1); double c2 = Cross(a2 - a2, b2 - a1); double c3 = Cross(b2 - b1, a1 - b1); double c4 = Cross(b2 - b1, a2 - b1); return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0; } bool OnSegment(point P, point a1, point a2)// 点是否在线段上 { return dcmp(Cross(a1 - P, a2 - P)) == 0 && dcmp(Dot(a1 - P, a2 - P)) < 0; } double PolygonArea(point *p, int n)// 凸多边形(多边形)的有向面积 { double area = 0; for(int i = 1; i < n - 1; i ++) area += Cross(p[i] - p[0], p[i + 1] - p[0]); return area / 2.0; }
模板来自 : -> 萌哒哒~毅哥
<<挑战程序设计竞赛>>读后感......
相关文章推荐
- 5-35 有理数均值 c 语言
- 3-UFT对象管理
- oracle 学习笔记
- List集合删除元素的时候删除不掉
- Linux USB 驱动开发实例(一) —— USB摄像头驱动实现源码分析
- 行内元素与块级元素
- FZU1327 优先队列
- zeroclipboard浏览器复制插件使用记录
- IOS 杂笔-11(实现在外部无法改变UIView的size)
- HDU 3715 Go Deeper 2-SAT 二分答案
- 构建之法心得
- android 自定义控件学习
- ubuntu下软件安装和卸载
- android网络技术-使用 HTTP协议访问网络
- nefu 943 黑屏
- 码农小汪-struts2学习6-国际化
- 附加作业3
- Java虚拟机解析篇之---内存模型
- centos 安装mysql,tomcat,jdk
- Java中Comparable与Comparator的区别