数学内容Day1

排列组合&数论

idy002老师的代码(day1)

#include<bits/stdc++.h>
const int N = 5000 + 10;
const int Mod = 1e9 + 7;

long long comb[N][N];

void init(int n) {
	for(int i = 0; i <= n; i++) {
		for(int j = 0; j <= i; j++) {
			if(j == 0 || j == i) 
				comb[i][j] = 1;
			else
				comb[i][j] = (comb[i-1][j-1] + comb[i-1][j]) % Mod;
		}
	}
}

void print(int s) {
	for(int i = 7; i >= 0; i--)
		printf("%d", (s>>i)&1);
	printf("\n");
}
void subset(int u) {
//	int u = 0x5;	//	0000 0101
	for(int s = u; s; s = (s - 1) & u) {
		print(s);
	}
	print(0);
}

int mpow(int a, int b, int m) {
	int rt=1;
	for(; b; b>>=1,a=(1LL*a*a)%m)
		if(b&1) rt=(1LL*rt*a)%m;
	return rt;
}

//	a * b % m
long long mul(long long a, long long b, long long m) {
	long long rt = 0;
	for(; b; b>>=1,a=(a+a)%m)
		if(b&1) rt=(rt+a)%m;
	return rt;
}

//	lucas
long long lucas(long long n, long long m, int p) {
	if(n == 0 && m == 0) return 1;
	if(n < m) return 0;
	return lucas(n / p, m / p, p) * comb[n % p][m % p] % p;
}

//	gcd
long long gcd(long long a, long long b) {
	return b == 0 ? a : gcd(b, a % b);
}

void exgcd(long long a, long long b, long long &d, long long &x, long long &y) {
	if(b == 0) {
		d = a, x = 1, y = 0;
	} else {
		long long x0, y0;
		exgcd(b, a % b, d, x0, y0);
		//	x0 * b + y0*(a - (a/b)*b) = d
		//	a * y0 + b * (x0 - (a/b)*y0) = d
		x = y0;
		y = x0 - (a / b) * y0;
	}
}

const int Mod = 1e9 + 7;

struct Matrix {
	int w[2][2];
	void zero() {
		for(int i = 0; i < 2; i++)
			for(int j = 0; j < 2; j++)
				w[i][j] = 0;
	}
	void unit() {
		for(int i = 0; i < 2; i++)
			for(int j = 0; j < 2; j++)
				w[i][j] = (i == j);
	}
	int *operator[](int i) {
		return w[i];
	}
};

Matrix operator*(const Matrix &r, const Matrix &s) {
	Matrix c;
	for(int i = 0; i < 2; i++)
		for(int j = 0; j < 2; j++) {
			c[i][j]  = 0;
			for(int k = 0; k < 2; k++) 
				c[i][j] = (c[i][j] + 1LL * r[i][k] * s[k][j])% Mod;
		}
	return c;
}

Matrix mpow(Matrix a, int b) {
	Matrix rt;
	for(rt.unit(); b; b>>=1,a=a*a)
		if(b & 1) rt=rt*a;
	return rt;
}

int primes[33], ptot;
vector<pair<int,int> > split(int n) {
	vector<pair<int,int> > stk;
	for(int i = 2; i * i <= n; i++) {
		if(n % i == 0) {
			stk.push_back(make_pair(i, 0));
			while(n % i == 0) {
				n /= i;
				stk.back().second++;
			}
		}
	}
	if(n != 1) {
		stk.push_back(make_pair(n, 1));
	}
	return stk;
}


#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;


int countbits(int s) {
	int rt = 0;
	while(s) {
		rt++;
		s -= s & -s;
	}
	return rt;
}
int count(int m, int n) {
	vector<int> stk;
	for(int i = 2; i * i <= n; i++) {
		if(n % i == 0) {
			stk.push_back(i);
			while(n % i == 0)
				n /= i;
		}
	}
	if(n != 1) stk.push_back(n);
	if(stk.size() == 0) return 1;
	int rt = 0;
	int u = (1<<stk.size()) - 1;
	for(int s = u; s; s = (s - 1) & u) {
		int mul = 1;
		for(int t = 0; t < (int)stk.size(); t++) {
			if((s>>t) & 1) mul *= stk[t];
		}
		if(countbits(s) & 1) 
			rt += m / mul;
		else
			rt -= m / mul;
	}
	return m - rt;
}

int main() {
	while(1) {
		int m, n;
		scanf("%d%d", &m, &n);
		printf("%d\n", count(m,n));
	}
}

我觉得他的这个 exgcd 实在不美观啊,我觉得不行并且搞了一套自己用的

long long X,Y,d;
void exgcd(long long a,long long b)
{
 if(b==0){X=1;Y=0;d=a;}
 else 
  {
   exgcd(b,a%b);
   long long t=X-a/b*Y;X=Y;Y=t;
  }
}

学习内容

排列组合
二项式定理                        及其推论

                           

可重排列
 
循环排列
 
区分盒子,不区分球
             
卡特兰数列                                                      递推式     
                   
容斥原理


Lucas


数论
最大公约数gcd && 最小公倍数lcm 


二元一次不等式

欧拉函数


其实我大部分都没有搞懂,但还是先贴上来再说吧


猜你喜欢

转载自blog.csdn.net/LoLiK1314/article/details/79309341