各种公式及模板
赞美老师的名言名句-24节气养生法
各种公式及模板 
1、         几何... 25 
1.1          注意... 25 
 
1.2
几何公式... 25 
 
1.3          多边形... 27 
1.4          多边形切割... 30 
 
1.5
浮点函数... 31 
 
1.6          面积... 36 
1.7          球面... 37 
 
1.8
三角形... 38 
 
1.9          三维几何... 40 
1.10        凸包... 47 
 
1.11
网格... 49 
 
1.12        圆... 49 
1.13        整数函数... 51 
 
2、
组合... 54 
 
1  28 
2.1 组合公式... 54
 
2.2 排列组合生成... 54 
 
2.3 生成gray码...
56 
 
2.4 置换(polya) 56 
 
2.5
字典序全排列... 57 
 
2.6 字典序组合... 57 
 
3、
结构... 58 
 
3.1 并查集... 58 
 
3.2 堆...
59 
 
3.3 线段树... 60 
 
3.4 子段和... 65
 
3.5 子阵和... 65 
 
4、         数论...
66 
 
4.1 阶乘最后非0位... 66 
 
4.2
模线性方程组... 67 
 
4.3 素数... 68 
2  28
 
4.4 欧拉函数... 69 
 
5、
数值计算... 70 
 
5.1 定积分计算(Romberg) 70 
5.2 多项式求根(牛顿法) 72 
 
5.3 周期性方程(追赶法) 73
 
6、         图论—NP搜索... 74 
 
6.1
最大团... 74 
 
6.2 最大团(n<64)(faster) 75 
7、         图论—连通性... 77 
 
7.1
无向图关键点(dfs邻接阵) 77 
 
7.2 无向图关键边(dfs邻接阵) 78
 
7.3 无向图的块(bfs邻接阵) 79 
 
7.4
无向图连通分支(dfsbfs邻接阵) 80 
 
7.5
有向图强连通分支(dfsbfs邻接阵) 81 
 
7.6 有向图最小点基(邻接阵)
82 
 
3  28 
8、         图论—匹配...
83 
 
8.1 二分图最大匹配(hungary邻接表) 83 
8.2 二分图最大匹配(hungary邻接阵) 84 
 
8.3
二分图最大匹配(hungary正向表) 84 
8.4二分图最佳匹配(kuhn_munkras邻接阵) 85 
 
8.5
一般图匹配(邻接表) 86 
 
8.6 一般图匹配(邻接阵) 87 
8.7 一般图匹配(正向表) 87 
 
9、
图论—网络流... 88 
 
9.1 最大流(邻接阵) 88 
 
9.2
上下界最大流(邻接阵) 89 
 
9.3 上下界最小流(邻接阵) 90 
9.4 最大流无流量(邻接阵) 91 
 
9.5 最小费用最大流(邻接阵)
91 
 
10、       图论—应用... 92 
 
10.1
欧拉回路(邻接阵) 92 
4  28 
 
10.2
树的前序表转化... 93 
 
10.3 树的优化算法... 94 
10.4 拓扑排序(邻接阵) 95 
 
10.5 最佳边割集... 96
 
10.6 最佳点割集... 97 
 
10.7 最小边割集...
98 
 
10.8 最小点割集... 99 
 
10.9
最小路径覆盖... 101 
 
11、       图论—支撑树... 101
 
11.1 最小生成树(kruskal邻接表) 101 
 
11.2
最小生成树(kruskal正向表) 103 
 
11.3
最小生成树(prim+binary_heap邻接表) 104 
 
11.4
最小生成树(prim+binary_heap正向表) 105 
 
11.5
最小生成树(prim+mapped_heap邻接表) 106 
 
11.6
最小生成树(prim+mapped_heap正向表) 108 
 
5  28
11.7 最小生成树(prim邻接阵) 109 
 
11.8
最小树形图(邻接阵) 109 
 
12、       图论—最短路径... 111
 
12.1 最短路径(单源bellman_ford邻接阵) 111 
12.2 最短路径(单源dijkstra+bfs邻接表) 111 
 
12.3
最短路径(单源dijkstra+bfs正向表) 112 
 
12.4
最短路径(单源dijkstra+binary_heap邻接表) 113 
 
12.5
最短路径(单源dijkstra+binary_heap正向表) 114 
 
12.6
最短路径(单源dijkstra+mapped_heap邻接表) 115 
 
12.7
最短路径(单源dijkstra+mapped_heap正向表) 116 
 
12.8
最短路径(单源dijkstra邻接阵) 117 
 
12.9
最短路径(多源floyd_warshall邻接阵) 118 
 
13、
应用... 118 
 
13.1 Joseph问题... 118 
13.2 N皇后构造解... 119 
 
13.3 布尔母函数... 120
6  28 
 
13.4 第k元素... 120 
13.5 幻方构造... 121 
 
13.6 模式匹配(kmp) 122
 
13.7 逆序对数... 123 
 
13.8 字符串最小表示...
123 
 
13.9 最长公共单调子序列... 124 
 
13.10
最长子序列... 125 
 
13.11 最大子串匹配... 126 
13.12 最大子段和... 127 
 
13.13 最大子阵和... 127
 
14、       其它... 128 
 
14.1
大数(只能处理正数) 128 
 
14.2 分数... 134 
14.3 矩阵... 136 
 
14.4 线性方程组... 138 
7  28 
14.5 线性相关... 140 
14.6 日期... 140 
 
  
 
1、       几何
1.1           注意 
1.
注意舍入方式(0.5的舍入方向);防止输出-0. 
 
  
 
2.
几何题注意多测试不对称数据. 
 
  
 
3.
整数几何注意xmult和dmult是否会出界; 
 
   符点几何注意eps的使用.
 
  
 
4. 避免使用斜率;注意除数是否会为0. 
 
 
5. 公式一定要化简后再代入. 
 
  
 
6.
判断同一个2*PI域内两角度差应该是 
8  28 
 
abs(a1-a2)
 
相等应该是 
 
abs(a1-a2)
 
 
7. 需要的话尽量使用atan2,注意:atan2(0,0)=0, 
   
atan2(1,0)=pi2,atan2(-1,0)=-pi2,atan2(0
,1)=0,atan2(0,-1)=
pi. 
 
  
 
8.
cross product = |u|*|v|*sin(a) 
 
   dot
product = |u|*|v|*cos(a) 
 
  
 
9.
(P1-P0)x(P2-P0)结果的意义: 
 
   正:
 
   负:
 
   0 :
 
9  28
  
 
10. 误差限缺省使用1e-8! 
1.2           几何公式 
三角形: 
 
1. 半周长
P=(a+b+c)2 
 
2. 面积
S=aHa2=absin(C)2=sqrt(P(P-a)(P-b)(P-c)) 
3. 中线
Ma=sqrt(2(b^2+c^2)-a^2)2=sqrt(b^2+c^2+2bccos(A))2
 
4. 角平分线
Ta=sqrt(bc((b+c)^2-a^2))(b+c)=2bccos(A2)(b+c)
 
5. 高线
Ha=bsin(C)=csin(B)=sqrt(b^2-((a^2+b^2-c^2)(2a))^2)
 
6. 内切圆半径 r=SP=asin(B2)sin(C2)sin((B+C)2)
 
               
=4Rsin(A2)sin(B2)sin(C
2)=sqrt((P-a)(P-b)(P-c)P) 
 
=Ptan(A2)tan(B2)tan(C2) 
 
7. 外接圆半径
R=abc(4S)=a(2sin(A))=b(2sin(B))=c(2sin(C))
 
  
 
四边形: 
10  28 
D1,D2为对角线,M对角线中点连线,A为对角线夹角 
 
1.
a^2+b^2+c^2+d^2=D1^2+D2^2+4M^2 
 
2.
S=D1D2sin(A)2 
 
(以下对圆的内接四边形) 
 
3.
ac+bd=D1D2 
 
4.
S=sqrt((P-a)(P-b)(P-c)(P-d)),P为半周长 
 
  
正n边形: 
 
R为外接圆半径,r为内切圆半径 
 
1. 中心角
A=2PIn 
 
2. 内角 C=(n-2)PIn 
 
3. 边长
a=2sqrt(R^2-r^2)=2Rsin(A2)=2rtan(A2) 
 
4.
面积 S=nar2=nr^2tan(A2)=nR^2sin(A)2=na^2(4tan(A2))
 
  
 
圆: 
 
11  28
1. 弧长 l=rA 
 
2. 弦长
a=2sqrt(2hr-h^2)=2rsin(A2) 
 
3. 弓形高
h=r-sqrt(r^2-a^24)=r(1-cos(A2))=atan(A4)2 
4. 扇形面积 S1=rl2=r^2A2 
 
5. 弓形面积
S2=(rl-a(r-h))2=r^2(A-sin(A))2 
 
  
棱柱: 
 
1. 体积 V=Ah,A为底面积,h为高 
 
2.
侧面积 S=lp,l为棱长,p为直截面周长 
 
3. 全面积 T=S+2A 
  
 
棱锥: 
 
1. 体积 V=Ah3,A为底面积,h为高
 
(以下对正棱锥) 
 
2. 侧面积
S=lp2,l为斜高,p为底面周长 
 
3. 全面积 T=S+A 
12  28
 
  
 
棱台: 
 
1. 体积
V=(A1+A2+sqrt(A1A2))h3,A1.A2为上下底面积,h为高 
(以下为正棱台) 
 
2. 侧面积
S=(p1+p2)l2,p1.p2为上下底面周长,l为斜高 
 
3. 全面积
T=S+A1+A2 
 
  
 
圆柱: 
 
1. 侧面积
S=2PIrh 
 
2. 全面积 T=2PIr(h+r) 
 
3. 体积
V=PIr^2h 
 
  
 
圆锥: 
 
1. 母线
l=sqrt(h^2+r^2) 
 
2. 侧面积 S=PIrl 
 
13
28 
3. 全面积 T=PIr(l+r) 
 
4. 体积
V=PIr^2h3 
 
  
 
圆台: 
 
1. 母线
l=sqrt(h^2+(r1-r2)^2) 
 
2. 侧面积 S=PI(r1+r2)l
 
3. 全面积 T=PIr1(l+r1)+PIr2(l+r2) 
4. 体积 V=PI(r1^2+r2^2+r1r2)h3 
 
  
球: 
 
1. 全面积 T=4PIr^2 
 
2. 体积
V=4PIr^33 
 
  
 
球台: 
 
1. 侧面积
S=2PIrh 
 
2. 全面积 T=PI(2rh+r1^2+r2^2) 
14
28 
 
3. 体积 V=PIh(3(r1^2+r2^2)+h^2)6
 
  
 
球扇形: 
 
1. 全面积
T=PIr(2h+r0),h为球冠高,r0为球冠底面半径 
 
2. 体积
V=2PIr^2h3 
 
1.3           多边形 
#include
 
#include 
#define MAXN 1000 
 
#define offset
10000 
 
#define eps 1e-8 
 
#define
zero(x) (((x)>0?(x):-(x))
#define
_sign(x) ((x)>eps?1:((x)<-eps?2:0)) 
struct point{double x,y;}; 
 
struct
line{point a,b;}; 
 
  
15  28
 
double xmult(point p1,point
p2,point p0){ 
 
       return 
(p1.x-p0.
x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); 
 
}
 
  
 
判定凸多边形,顶点按顺时针或逆时针给出,允许相邻边共线
 
int is_convex(int n,point* p){ 
 
int i,s[3]={1,1,1}; 
 
       for
(i=0;i
s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0;
 
       return s[1]|s[2]; 
 
} 
  
 
判定凸多边形,顶点按顺时针或逆时针给出,不允许相邻边共线 
int is_convex_v2(int n,point* p){ 
 
16
28 
       int i,s[3]={1,1,1}; 
 
for (i=0;i
s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0;
 
       return s[0]&&s[1]|s[2]; 
 
}
 
  
 
判点在凸多边形内或多边形边上,顶点按顺时针或逆时针给出
 
int inside_convex(point q,int n,point*
p){ 
 
       int i,s[3]={1,1,1}; 
 
for (i=0;i
s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0; 
 
return s[1]|s[2]; 
 
} 
 
  
判点在凸多边形内,顶点按顺时针或逆时针给出,在多边形边上返
回0 
17  28
 
int inside_convex_v2(point q,int
n,point* p){ 
 
       int i,s[3]={1,1,1};
 
       for (i=0;i
s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0; 
 
return s[0]&&s[1]|s[2]; 
 
} 
 
  
判点在任意多边形内,顶点按顺时针或逆时针给出 
on_edge表示点在多边形边上时的返回值,offset为多边形坐标上
限 
int inside_polygon(point q,int n,point* p,int
on_edge=1){ 
 
       point q2; 
 
int i=0,count; 
 
       while (i
              for 
(count=i=0,q2.x=rand()+o
ffset,q2.y=rand()+offset;i
18  28
                     if 
(zero(xmult
(q,p[i],p[(i+1)%n]))&&(p[i].x-q.x)*(p[(i+1)%n].x-q.x)
                            return
on_edge; 
 
                     else if
(zero(xmult(q,q2,p[i]))) 
 
break; 
 
                     else if 
(
xmult(q,p[i],q2)*xmult(q,p[(i+1)%n],q2)<-eps&&xmul
t(p[i],q
,p[(i+1)%n])*xmult(p[i],q2,p[(i+1)%n])
<-eps) 
 
count++; 
 
       return count&1; 
} 
 
  
 
inline int
opposite_side(point p1,point p2,point l1,point
l2){ 
 
       return
xmult(l1,p1,l2)*xmult(l1,p2,l2)<-eps; 
 
}
 
  
 
inline int dot_online_in(point
p,point l1,point l2){ 
19  28 
 
return 
zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-
p.x)
} 
 
  
判线段在任意多边形内,顶点按顺时针或逆时针给出,与边界相交
返回1 
int inside_polygon(point l1,point l2,int
n,point* p){ 
 
       point t[MAXN],tt;
 
       int i,j,k=0; 
 
       if (!inside_polygon(l1,n,p)||!inside_polygon(l2,n,p
)) 
 
              return 0; 
 
for (i=0;i
              if 
(o
pposite_side(l1,l2,p[i],p[(i+1)%n])&&opposite_side
(p[i],p
[(i+1)%n],l1,l2)) 
 
return 0; 
 
20  28 
else if (dot_online_in(l1,p[i],p[(i+1)%n])) 
                     t[k++]=l1; 
 
else if (dot_online_in(l2,p[i],p[(i+1)%n])) 
                     t[k++]=l2; 
 
else if (dot_online_in(p[i],l1,l2)) 
 
t[k++]=p[i]; 
 
       for (i=0;i
              for (j=i+1;j
                     tt.x=(t[i].x+t[j].x)2;
 
tt.y=(t[i].y+t[j].y)2; 
 
if (!inside_polygon(tt,n,p)) 
 
return 0;                
 
              }
 
       return 1; 
 
} 
 
21  28 
 
point intersection(line
u,line v){ 
 
       point ret=u.a; 
       double 
t=((u.a.x-v.a.x)*(v.a.y-v.b.
y)-(u.a.y-v.a.y)*(v.a.x-v.b.x)) 
 
((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.
a.x-v.b.x)); 
 
ret.x+=(u.b.x-u.a.x)*t; 
 
ret.y+=(u.b.y-u.a.y)*t; 
 
       return
ret; 
 
} 
 
  
 
point
barycenter(point a,point b,point c){ 
 
line u,v; 
 
       u.a.x=(a.x+b.x)2; 
       u.a.y=(a.y+b.y)2; 
 
u.b=c; 
 
22  28 
v.a.x=(a.x+c.x)2; 
 
v.a.y=(a.y+c.y)2; 
 
       v.b=b; 
 
return intersection(u,v); 
 
} 
 
 
多边形重心 
 
point barycenter(int
n,point* p){ 
 
       point ret,t; 
       double t1=0,t2; 
 
       int i;
 
       ret.x=ret.y=0; 
 
       for
(i=1;i
              if
(fabs(t2=xmult(p[0],p[i],p[i+1]))>eps){ 
 
t=barycenter(p[0],p[i],p[i+1]); 
 
ret.x+=t.x*t2; 
23  28 
 
ret.y+=t.y*t2; 
 
t1+=t2; 
 
              } 
 
if (fabs(t1)>eps) 
 
ret.x=t1,ret.y=t1; 
 
       return ret;
 
} 
 
1.4           多边形切割 
多边形切割
 
可用于半平面交 
 
#define MAXN 100 
#define eps 1e-8 
 
#define zero(x)
(((x)>0?(x):-(x))
struct
point{double x,y;}; 
 
  
 
double
xmult(point p1,point p2,point p0){ 
24  28
 
       return 
(p1.x-p0.x)*(p2.
y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); 
 
} 
  
 
int same_side(point p1,point
p2,point l1,point l2){ 
 
       return
xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps; 
 
}
 
  
 
point intersection(point
u1,point u2,point v1,point v2){ 
 
point ret=u1; 
 
       double 
t=((u1.x-
v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x)) 
                     
((u1.x-u2.x)*(v1.y-v2
.y)-(u1.y-u2.y)*(v1.x-v2.x)); 
 
ret.x+=(u2.x-u1.x)*t; 
 
ret.y+=(u2.y-u1.y)*t; 
 
       return ret;
25  28 
 
} 
 
  
将多边形沿l1,l2确定的直线切割在side侧切割,保证l1,l2,side
不共线
 
void polygon_cut(int& n,point* p,point
l1,point l2,point 
side){ 
 
       point
pp[100]; 
 
       int m=0,i; 
 
for (i=0;i
              if
(same_side(p[i],side,l1,l2)) 
 
pp[m++]=p[i]; 
 
              if 
(!same
_side(p[i],p[(i+1)%n],l1,l2)&&!(zero(xmult(p[i],l1
,l2
))&&zero(xmult(p[(i+1)%n],l1,l2)))) 
pp[m++]=intersection(p[i],p[(i+1)%n],l1,l2);
 
       } 
 
       for
(n=i=0;i
 
if 
(!i||!zero(pp[i].x-pp[i-1].x)||!zero(pp[i].
y-pp[i-1].y)) 
 
p[n++]=pp[i]; 
 
       if
(zero(p[n-1].x-p[0].x)&&zero(p[n-1].y-p[0].y))
 
              n--; 
 
       if
(n<3) 
 
              n=0; 
 
} 
1.5           浮点函数 
浮点几何函数库 
#include 
 
#define eps 1e-8
 
#define zero(x) (((x)>0?(x):-(x))
struct point{double x,y;}; 
struct line{point a,b;}; 
 
  
27  28 
计算cross product
(P1-P0)x(P2-P0) 
 
double xmult(point
p1,point p2,point p0){ 
 
       return 
(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
 
} 
 
double xmult(double x1,double
y1,doubl 
 
28  28