1、容斥原理。
如果班里有15个人喜欢物理,10个人喜欢英语,16个人喜欢数学,那么班里面有多少个人呢?
10+16+15显然是错的,因为存在一个人既喜欢物理也喜欢英语,那么就把这些重复加的人的数量给剪掉。
也就是减去既喜欢物理又喜欢英语的人,既喜欢英语又喜欢数学的人,既喜欢数学又喜欢物理的人,这样就把刚才多加进去的人全部剪掉了,
可是这样既喜欢英语又喜欢数学又喜欢英语的这么一个人,他在这次剪的过程剪了2次,那么就再把喜欢3个科目的人加起来,这就是容斥原理。
也就是|A∪B∪C|=|A|+|B|+|C|-|A∩B|-|B∩C|-|C∩A|+|A∩B∩C|。
2、有重复元素的全排列。
给定k个元素,其中第i个元素有ai个,求全排序个数。
令所有n i 之和为n,再设答案为x。首先做全排列,然后把所有元素编号,其中第s种元素
编号为1~n s (例如,有3个a,两个b,先排列成aabba,然后可以编号为a 1 a 3 b 2 b 1 a 2 )。这样
做以后,由于编号后所有元素均不相同,方案总数为n的全排列数n!。根据乘法原理,得到
了一个方程:n 1 !n 2 !n 3 !…n k x!=n!,移项即可。
也就是先全部都包括在里面,然后把重复的去除。
3、有重复选择的组合。
杨辉三角
C(K,N)=K/(N-K+1)C(K-1,N)。可以想想为什么有这个公式。
然后可以根据这个公式递推出C(K,N)。
#include
using namespace std;
int main(){
int a,i,j,k,n,m,b[100];
cin>> n;
b[0]=1;
for(i=1;i<=n;i++)
b[i]=b[i-1]*(n-i+1)/i;
for(i=0;i<=n;i++)
cout << b[i] <<" ";
return 0;
}
其中n为多少就是杨辉三角的第几+1行。
不难看出,约数的个数意思也就是其各个因子的个数,如对于84=(2^2)*(3^1)*(7^1).
也就是其既可以整除2和整除2^2,3,7。也就是相当与其唯一分解式各个式的指数可以取0、1、2、。。。到a1,84也就是对于2,可以取0、1、2,
对于3,可以取0、1,对于7,可以取0、1。也就是其因子可以由哪些素数组成。
欧拉函数,给定一个N,找出所有n中与n互素的数,也就是这两个数的最大公约数为1。
用容斥原理。首先从总数n中分别减去是p 1 , p 2 , … , p k 的倍数的个数(对于素数p来
说,“与p互素”和“不是p的倍数”等价),即 ,然后加上“同时是两个素因子
的倍数”的个数 ,再减去“同时是3个素因子的倍数”——写成一个“学术
味比较浓”的公式就是:
其可以写为=(1-1/p1)(1-1/p2)(1-1/p3)...的形式。
1、从1开始到n,找到gcd(i,n)==1的那个数,然后打上标记,再把其的倍数打上标记,循环到n,可以筛选出互素数。
#include
using namespace std;
bool vis[50000];
int gcd(int a,int b){
//cout << a << "\t" << b <> n;
// cout << gcd(n,5) << endl;
for(i=1;i<=n;i++)if(!vis[i]&&gcd(n,i)!=1)
for(j=i;j<=n;j+=i){
vis[j]=1;
// cout << j << endl;
}
int f1=0;
for(i=1;i<=n;i++){
if(!vis[i])
f1++;
}
cout << f1<< endl;
return 0;
}
2、如对84,n=n/i*(i-1),意思是减去为i倍数的数,