gcd+ecgcd+lcm
#include <cstdio>
#include <iostream>
using namespace std;
int gcd ( int a, int b) {
return b== 0 ? a: gcd ( b, a% b) ;
}
int exgcd ( int a, int b, int & x, int & y) {
if ( b== 0 ) { x= 1 , y= 0 ; return a; }
int t= exgcd ( b, a% b, x, y) ;
int x0= x, y0= y;
x= y0, y= x0- ( a/ b) * y0;
return t;
}
int lcm ( int a, int b) {
return a* b/ gcd ( a, b) ;
}
Inv (乘法逆元)
( a/ b) % MOD= ( a* inv ( b, MOD) ) % MOD
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
#define ll long long
ll exgcd ( ll a, ll b, ll & x, ll & y) {
if ( a% b== 0 ) {
x= 0ll ; y= 1ll ;
return b;
}
ll v, tx, ty;
v= exgcd ( b, a% b, tx, ty) ;
x= ty;
y= tx- a/ b* ty;
return v;
}
ll inv ( ll a, ll p) {
if ( ! a) return 0ll ;
ll x, y;
exgcd ( a, p, x, y) ;
x= ( x% p+ p) % p;
return x;
}
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
ll quick_pow ( ll a, ll b, ll mod) {
ll ans= 1 ;
while ( b)
{
if ( b& 1 ) ans= ( ans* a) % mod;
a= ( a* a) % mod;
b>>= 1 ;
}
return ans;
}
ll inv ( ll x, ll mod) {
return quick_pow ( x, mod- 2 , mod) ;
}
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
卡特兰数
#include <bits/stdc++.h>
using namespace std;
int a[ 110 ] [ 1000 ] ;
int b[ 1000 ] ;
void catalan ( ) {
a[ 1 ] [ 0 ] = 1 ;
b[ 1 ] = 1 ;
int len= 1 ;
for ( int i= 2 ; i<= 100 ; i++ ) {
for ( int j= 0 ; j< len; j++ )
a[ i] [ j] = a[ i- 1 ] [ j] * ( 4 * ( i- 1 ) + 2 ) ;
int carry= 0 , temp= 0 ;
for ( int j= 0 ; j< len; j++ ) {
temp= a[ i] [ j] + carry;
a[ i] [ j] = temp% 10 ;
carry= temp/ 10 ;
}
while ( carry) {
a[ i] [ len++ ] = carry% 10 ;
carry/ = 10 ;
}
carry= 0 ;
for ( int j= len- 1 ; j>= 0 ; j-- ) {
temp= carry* 10 + a[ i] [ j] ;
a[ i] [ j] = temp/ ( i+ 1 ) ;
carry= temp% ( i+ 1 ) ;
}
while ( ! a[ i] [ len- 1 ] ) len-- ;
b[ i] = len;
}
}
int main ( ) {
catalan ( ) ;
int n;
while ( cin>> n) {
for ( int i= b[ n] - 1 ; i>= 0 ; i-- ) {
cout<< a[ n] [ i] ;
}
cout<< endl;
}
return 0 ;
}
埃氏筛 欧拉筛
#include <algorithm>
#include <stdio.h>
#include <string.h>
#define maxn 10000010
using namespace std;
bool u[ maxn] ;
int su[ maxn] ;
int num= 1 ;
void Es ( int n) {
int i, j;
memset ( u, true, sizeof ( u) ) ;
for ( i= 2 ; i< n; i++ ) {
if ( u[ i] ) su[ num++ ] = i;
for ( j= 1 ; j< num; j++ ) {
if ( i* su[ j] > n) break ;
u[ i* su[ j] ] = false;
if ( i% su[ j] == 0 ) break ;
}
}
}
void Is ( int n) {
memset ( u, true, sizeof ( u) ) ;
for ( int i= 2 ; i< n; i++ ) {
if ( u[ i] ) {
su[ num++ ] = i;
for ( int j= i+ i; j< n; j+ = i) {
u[ j] = false;
}
}
}
}
筛选法+试除法
#include <bits/stdc++.h>
using namespace std;
#define maxn 11000
bool u[ maxn] ;
int su[ maxn] ;
int a[ maxn] ;
long long s[ maxn] ;
int num= 1 ;
void Es ( int n) {
int i, j;
memset ( u, true, sizeof ( u) ) ;
for ( i= 2 ; i< n; i++ ) {
if ( u[ i] ) su[ num++ ] = i;
for ( j= 1 ; j< num; j++ ) {
if ( i* su[ j] > n) break ;
u[ i* su[ j] ] = false;
if ( i% su[ j] == 0 ) break ;
}
}
}
bool pri ( long long n) {
if ( n< 10000 ) {
return u[ n] ;
} else {
for ( int i= 1 ; i< num; i++ ) {
if ( n% su[ i] == 0 ) return false;
}
return true;
}
}
Miller_Rabin素性测试
#include <bits/stdc++.h>
using namespace std;
int prime[ 10 ] = { 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 } ;
typedef long long ll;
ll pow ( ll x, ll n, ll mod) {
ll res= 1 ;
while ( n> 0 ) {
if ( n% 2 == 1 ) {
res= res* x;
res= res% mod;
}
x= x* x;
x= x% mod;
n>>= 1 ;
}
return res;
}
ll mulit ( ll a, ll b, ll c) {
ll ans= 0 ;
ll res= a;
while ( b) {
if ( b& 1 )
ans= ( ans+ res) % c;
res= ( res+ res) % c;
b>>= 1 ;
}
return ans;
}
bool Miller_Rabin ( int x)
{
int i, j, k;
int s= 0 , t= x- 1 ;
if ( x== 2 ) return true;
if ( x< 2 || ! ( x& 1 ) ) return false;
while ( ! ( t& 1 ) )
{
s++ ;
t>>= 1 ;
}
for ( i= 0 ; i< 10 && prime[ i] < x; ++ i)
{
int a= prime[ i] ;
int b= pow ( a, t, x) ;
for ( j= 1 ; j<= s; ++ j)
{
k= mulit ( b, b, x) ;
if ( k== 1 && b!= 1 && b!= x- 1 )
return false;
b= k;
}
if ( b!= 1 ) return false;
}
return true;
}
int main ( )
{
int x;
scanf ( "%d" , & x) ;
if ( Miller_Rabin ( x) ) printf ( "Yes" ) ;
else printf ( "No" ) ;
return 0 ;
}
欧拉公式
inline ll phi ( ll n) {
if ( n == 1 ) return 1 ;
ll ans = n, m = sqrt ( n) ;
for ( register ll i = 2 ; i <= m; i++ )
if ( n % i == 0 ) {
ans = ans / i * ( i - 1 ) ;
while ( n % i == 0 ) n / = i;
}
if ( n > 1 ) ans = ans / n * ( n - 1 ) ;
return ans;
}
卢卡斯定理求组合数
#include <bits/stdc++.h>
#define N 100010
using namespace std;
typedef long long ll;
ll a[ N] ;
int p;
ll pow ( ll y, int z, int p) {
y% = p; ll ans= 1 ;
for ( int i= z; i; i>>= 1 , y= y* y% p) if ( i& 1 ) ans= ans* y% p;
return ans;
}
ll C ( ll n, ll m) {
if ( m> n) return 0 ;
return ( ( a[ n] * pow ( a[ m] , p- 2 , p) ) % p* pow ( a[ n- m] , p- 2 , p) % p) ;
}
ll Lucas ( ll n, ll m) {
if ( ! m) return 1 ;
return C ( n% p, m% p) * Lucas ( n/ p, m/ p) % p;
}
inline int read ( ) {
int f= 1 , x= 0 ; char ch;
do { ch= getchar ( ) ; if ( ch== '-' ) f= - 1 ; } while ( ch< '0' || ch> '9' ) ;
do { x= x* 10 + ch- '0' ; ch= getchar ( ) ; } while ( ch>= '0' && ch<= '9' ) ;
return f* x;
}
int main ( ) {
int T= read ( ) ;
while ( T-- ) {
int n= read ( ) , m= read ( ) ; p= read ( ) ;
a[ 0 ] = 1 ;
for ( int i= 1 ; i<= p; i++ ) a[ i] = ( a[ i- 1 ] * i) % p;
cout<< Lucas ( n+ m, n) << endl;
}
}
费马小定理+快速幂求组合数
#include <bits/stdc++.h>
#define mod 1000000007
typedef long long LL;
const int maxn = 100000 + 10 ;
LL fac[ maxn] ;
LL power ( LL a, LL b) {
a% = mod;
LL ans = 1 ;
while ( b) {
if ( b& 1 ) ans = ( ans* a) % mod;
b>>= 1 ;
a = ( a* a) % mod;
}
return ans;
}
LL inv ( LL a) {
return power ( a, mod- 2 ) % mod;
}
void solve ( ) {
fac[ 0 ] = 1 ;
for ( int i = 1 ; i<= maxn- 1 ; i++ ) {
fac[ i] = ( fac[ i- 1 ] * i) % mod;
}
}
LL comb ( int n, int k) {
if ( k> n) return 0 ;
return ( fac[ n] * inv ( fac[ k] ) % mod* inv ( fac[ n- k] ) % mod) % mod;
}
int main ( )
{
solve ( ) ;
int n, k;
while ( scanf ( "%d%d" , & n, & k) != EOF ) {
printf ( "%lld\n" , comb ( n, k) ) ;
}
return 0 ;
}
欧拉函数求与n互质的个数
#include <cstdio>
int oula ( int n) {
int ou= n;
for ( int i= 2 ; i* i<= n; i++ ) {
if ( n% i== 0 ) {
ou- = ou/ i;
while ( n% i== 0 ) {
n= n/ i;
}
}
}
if ( n> 1 ) {
return ou- = ou/ n;
}
return ou;
}
int main ( ) {
int n;
while ( ~ scanf ( "%d" , & n) && n) {
printf ( "%d\n" , oula ( n) ) ;
}
return 0 ;
}