老牛镇楼
四. 数学知识
4.1 质数
试除法判定质数
bool is_prime ( int x)
{
if ( x < 2 ) return false ;
for ( int i = 2 ; i <= x / i; i ++ )
if ( x % i == 0 )
return false ;
return true ;
}
试除法分解质因数
int primes[ N] , cnt;
bool st[ N] ;
void get_primes ( int n)
{
for ( int i = 2 ; i <= n; i ++ )
{
if ( st[ i] ) continue ;
primes[ cnt ++ ] = i;
for ( int j = i + i; j <= n; j += i)
st[ j] = true ;
}
}
线性筛法求素数
int primes[ N] , cnt;
bool st[ N] ;
void get_primes ( int n)
{
for ( int i = 2 ; i <= n; i ++ )
{
if ( ! st[ i] ) primes[ cnt ++ ] = i;
for ( int j = 0 ; primes[ j] <= n / i; j ++ )
{
st[ primes[ j] * i] = true ;
if ( i % primes[ j] == 0 ) break ;
}
}
}
4.2 约数
试除法求所有约数
vector< int > get_divisors ( int x)
{
vector< int > res;
for ( int i = 1 ; i <= x / i; i ++ )
if ( x % i == 0 )
{
res. push_back ( i) ;
if ( i != x / i) res. push_back ( x / i) ;
}
sort ( res. begin ( ) , res. end ( ) ) ;
return res;
}
约数个数和约数之和
如果 N = p1^ c1 * p2^ c2 * . . . * pk^ ck
约数个数: ( c1 + 1 ) * ( c2 + 1 ) * . . . * ( ck + 1 )
约数之和: ( p1^ 0 + p1^ 1 + . . . + p1^ c1) * . . . * ( pk^ 0 + pk^ 1 + . . . + pk^ ck)
4.3 快速幂
求 m^ k mod p,时间复杂度 O ( logk) 。
int qmi ( int m, int k, int p)
{
int res = 1 % p, t = m;
while ( k)
{
if ( k& 1 ) res = res * t % p;
t = t * t % p;
k >>= 1 ;
}
return res;
}
4.4 辗转相除法
GCD 求最大公约数
int gcd ( int big, int small)
{
if ( small > big) swap ( big, small) ;
int temp;
while ( small != 0 ) {
if ( small > big) swap ( big, small) ;
temp = big % small;
big = small;
small = temp;
}
return ( big) ;
}
LCMc 求最小公倍数
int gcd ( int big, int small)
{
if ( small > big) swap ( big, small) ;
int temp;
while ( small != 0 ) {
if ( small > big) swap ( big, small) ;
temp = big % small;
big = small;
small = temp;
}
return ( big) ;
}
4.5几何计算
向量基本用法
struct node {
double x;
double y;
} ;
typedef node Vector;
Vector operator + ( Vector A, Vector B) { return Vector ( A. x + B. x, A. y + B. y) ; }
Vector operator - ( Point A, Point B) { return Vector ( A. x - B. y, 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) ; }
double Dot ( Vector A, Vector B) { 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) {
return A. x* B. y - A. y* B. x;
}
Vector Rotate ( Vector A, double rad)
return Vector ( A. x* cos ( rad) - A. y* sin ( rad) , A. x* sin ( rad) + A. y* cos ( rad) ) ;
}
Point 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;
}
求多边形面积
node G[ maxn] ;
int n;
double Cross ( node a, node b) {
return a. x* b. y - a. y* b. x;
}
int main ( )
{
while ( scanf ( "%d" , & n) != EOF && n) {
for ( int i = 0 ; i < n; i++ )
scanf ( "%lf %lf" , & G[ i] . x, & G[ i] . y) ;
double sum = 0 ;
G[ n] . x = G[ 0 ] . x;
G[ n] . y = G[ 0 ] . y;
for ( int i = 0 ; i < n; i++ ) {
sum += Cross ( G[ i] , G[ i + 1 ] ) ;
}
sum = sum / 2.0 ;
printf ( "%.1f\n" , sum) ;
}
system ( "pause" ) ;
return 0 ;
}
判断线段相交
node P[ 35 ] [ 105 ] ;
double Cross_Prouct ( node A, node B, node C) {
return ( B. x- A. x) * ( C. y- A. y) - ( B. y- A. y) * ( C. x- A. x) ;
}
bool Intersect ( node A, node B, node C, node D) {
if ( min ( A. x, B. x) <= max ( C. x, D. x) &&
min ( C. x, D. x) <= max ( A. x, B. x) &&
min ( A. y, B. y) <= max ( C. y, D. y) &&
min ( C. y, D. y) <= max ( A. y, B. y) &&
Cross_Prouct ( A, B, C) * Cross_Prouct ( A, B, D) < 0 &&
Cross_Prouct ( C, D, A) * Cross_Prouct ( C, D, B) < 0 )
return true ;
else return false ;
}
求三角形外心
Point circumcenter ( const Point & a, const Point & b, const Point & c) {
Point ret;
double a1 = b. x - a. x, b1 = b. y - a. y, c1 = ( a1* a1 + b1* b1) / 2 ;
double a2 = c. x - a. x, b2 = c. y - a. y, c2 = ( a2* a2 + b2* b2) / 2 ;
double d = a1* b2 - a2* b1;
ret. x = a. x + ( c1* b2 - c2* b1) / d;
ret. y = a. y + ( a1* c2 - a2* c1) / d;
return ret;
}
极角排序
double cross ( point p1, point p2, point q1, point q2) {
return ( q2. y - q1. y) * ( p2. x - p1. x) - ( q2. x - q1. x) * ( p2. y - p1. y) ;
}
bool cmp ( point a, point b) {
point o;
o. x = o. y = 0 ;
return cross ( o, b, o, a) < 0 ;
}
sort ( convex + 1 , convex + cnt, cmp) ;