容斥原理学习

简单入门题目:

UVA10325   The lottery  http://vjudge.net/vjudge/contest/view.action?cid=53767#problem/A

设A[I]表示 是其中i个数的倍数的个数

SUM=A[1]-A[2]+A[3]-A[4]。。。。。

ANS=N-SUM;

代码如下:


[cpp] view plaincopy
  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #define LL long long
  5. using namespace std;
  6. LL a[15];
  7. LL gcd(LL a,LL b){
  8. if(b)
  9. return gcd(b,a%b);
  10. return a;
  11. }
  12. LL lcm(LL a,LL b){
  13. return a/gcd(a,b)*b;
  14. }
  15. int main()
  16. {
  17. int m;
  18. LL n,ans;
  19. while(cin>>n>>m){
  20. for(int i=0;i<m;i++)
  21. cin>>a[i];
  22. ans=0;
  23. for(int i=1;i<(1<<m);i++){
  24. LL l=1,flag=0;
  25. for(int j=0;j<m;j++){
  26. if((1<<j)&i){
  27. l=lcm(l,a[j]);
  28. if(l>n) break;
  29. flag++;
  30. }
  31. }
  32. if(flag&1)
  33. ans+=n/l;
  34. else
  35. ans-=n/l;
  36. }
  37. cout<<n-ans<<endl;
  38. }
  39. return 0;
  40. }

SPOJ   Another Game With Numbers   http://vjudge.net/vjudge/contest/view.action?cid=53767#problem/C

思路同上。

代码如下:

[cpp] view
plain
copy

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #define LL long long
  5. using namespace std;
  6. LL a[15];
  7. LL gcd(LL a,LL b){
  8. if(b)
  9. return gcd(b,a%b);
  10. return a;
  11. }
  12. LL lcm(LL a,LL b){
  13. return a/gcd(a,b)*b;
  14. }
  15. int main()
  16. {
  17. int m;
  18. LL n,ans;
  19. while(cin>>n>>m){
  20. for(int i=0;i<m;i++)
  21. cin>>a[i];
  22. ans=0;
  23. for(int i=1;i<(1<<m);i++){
  24. LL l=1,flag=0;
  25. for(int j=0;j<m;j++){
  26. if((1<<j)&i){
  27. l=lcm(l,a[j]);
  28. if(l>n) break;
  29. flag++;
  30. }
  31. }
  32. if(flag&1)
  33. ans+=n/l;
  34. else
  35. ans-=n/l;
  36. }
  37. cout<<n-ans<<endl;
  38. }
  39. return 0;
  40. }

UVA 11806 Cheerleaders   http://vjudge.net/vjudge/contest/view.action?cid=53767#problem/B

分析:

题目的意思就是 m*n个格子 在上面放k个  且第一行第一列最后一行最后一列都必须得放

反面考虑,考虑所有不符合条件的情况 ,一共有15种 ,然后用所有的情况减去即可;

代码如下:

[cpp] view
plain
copy

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #define LL long long
  5. using namespace std;
  6. const int maxn = 410;
  7. const int mod = 1000007;
  8. int com[maxn][maxn];
  9. void init(){
  10. memset(com,0,sizeof(com));
  11. for(int i=0;i<maxn;i++)
  12. com[i][0]=1;
  13. for(int i=1;i<maxn;i++){
  14. for(int j=1;j<=i;j++)
  15. com[i][j]=(com[i-1][j-1]%mod+com[i-1][j]%mod)%mod;
  16. }
  17. }
  18. int n,m,k;
  19. int solve(){
  20. int ans=0;
  21. for(int i=1;i<(1<<4);i++){
  22. int num=0,r=n,c=m;
  23. if(i&1) r--,num++;
  24. if(i&2) r--,num++;
  25. if(i&4) c--,num++;
  26. if(i&8) c--,num++;
  27. if(num%2==0)
  28. ans=(ans+mod-com[r*c][k])%mod;
  29. else
  30. ans=(ans+com[r*c][k])%mod;
  31. }
  32. return (com[m*n][k]-ans+mod)%mod;
  33. }
  34. int main()
  35. {
  36. int t,cnt=1;
  37. init();
  38. cin>>t;
  39. while(t--){
  40. cin>>n>>m>>k;
  41. int ans=solve();
  42. printf("Case %d: %d\n",cnt++,ans);
  43. }
  44. return 0;
  45. }

POJ 3904  Sky Code :http://poj.org/problem?id=3904

分析:

反面考虑,求出取出四个数的所有情况中 GCD(A,B,C,D)!=1的情况;我们只需将每一个数都给素因子分解,然后看使用不重复的素因子所能组成的因子的个数,并统计组成该因子 的素因子的个数

例如  形成的的因子2 的个数 为a,形成因子3的个数为b,形成6的因子的个数为c  则cnt=com(a,4)+com(b,4)-com(c,4);

代码如下:

[cpp] view
plain
copy

  1. #include<iostream>
  2. #include<cstdlib>
  3. #include<stdio.h>
  4. #include<memory.h>
  5. #define maxn 10005
  6. using namespace std;
  7. long long Count[maxn];
  8. long long num[maxn];
  9. long long p[maxn];
  10. long long prime[maxn];
  11. void init()
  12. {
  13. memset(p,0,sizeof(p));
  14. memset(num,0,sizeof(num));
  15. for(long long i=4;i<maxn;i++)
  16. p[i]=i*(i-1)*(i-2)*(i-3)/24;
  17. }
  18. void solve(long long  n)
  19. {
  20. long long  tol=0;
  21. for(long long  i=2;i*i<=n;i++)
  22. {
  23. if(n%i==0)
  24. {
  25. prime[tol++]=i;
  26. }
  27. while(n%i==0)
  28. n/=i;
  29. }
  30. if(n!=1)
  31. prime[tol++]=n;
  32. for(long long  i=1;i<(1<<tol);i++)
  33. {
  34. long long k=1;
  35. long long sum=0;
  36. for(long long  j=0;j<tol;j++)
  37. {
  38. if(i&(1<<j))
  39. {
  40. k*=prime[j];
  41. sum++;
  42. }
  43. }
  44. Count[k]++;//记录当前因子的个数
  45. num[k]=sum;//记录当前因子是由多少个素因子组成
  46. }
  47. }
  48. int main()
  49. {
  50. init();
  51. long long  n;
  52. long long  m;
  53. while(scanf("%lld",&n)!=EOF)
  54. {
  55. memset(Count,0,sizeof(Count));
  56. for(long long  i=0;i<n;i++)
  57. {
  58. scanf("%lld",&m);
  59. solve(m);
  60. }
  61. long long ans=0;
  62. for(long long  i=0;i<maxn;i++)
  63. {
  64. if(Count[i])
  65. {
  66. if(num[i]%2)
  67. {
  68. ans+=p[Count[i]];
  69. }
  70. else
  71. ans-=p[Count[i]];
  72. }
  73. }
  74. cout<<p[n]-ans<<endl;
  75. }
  76. return 0;
  77. }

SPOJ 4168 Square-free integers

http://vjudge.net/vjudge/contest/view.action?cid=53767#problem/E

分析:

求1~n中有多少个数可以写成 x^2,我们可以把这样的数写成 p^(2*q),

1~n中这样的数的个数为n/(p*p);中间重复的数我们根据容斥原理可以去掉

系数为莫比乌斯函数值

代码如下:

[cpp] view
plain
copy

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. using namespace std;
  5. typedef long long LL;
  6. const int maxn = 10000100;
  7. bool p[maxn];
  8. int mu[maxn],prime[maxn],cnt;
  9. //线性筛选求莫比乌斯反演
  10. void Init()
  11. {
  12. memset(p,0,sizeof(p));
  13. mu[1] = 1;
  14. cnt = 0;
  15. for(int i=2; i<maxn; i++){
  16. if(!p[i]){
  17. prime[cnt++] = i;
  18. mu[i] = -1;
  19. }
  20. for(int j=0; j<cnt&&i*prime[j]<maxn; j++){
  21. p[i*prime[j]] = 1;
  22. if(i%prime[j]) mu[i*prime[j]] = mu[prime[j]]*mu[i];
  23. else
  24. break;
  25. }
  26. }
  27. }
  28. int main()
  29. {
  30. Init();
  31. LL n,ans;
  32. int ca;
  33. scanf("%d",&ca);
  34. while(ca--){
  35. scanf("%lld",&n);
  36. ans=0;
  37. for(int i=1;i<=n/i;i++){
  38. if(mu[i])
  39. ans+=n/i/i*mu[i];
  40. }
  41. printf("%lld\n",ans);
  42. }
  43. return 0;
  44. }
时间: 2024-10-30 21:52:15

容斥原理学习的相关文章

容斥原理学习之路【容斥原理】

2014年12月8-14日,我的目标是完全搞懂容斥原理,顺便整理一下模板! 容斥原理在数学上应该算是很容易,这里就不再叙述! 以下面的一道题目为例:给出2个数字m,n;求1-m中有多少个数字与n互质(保证所有数字不超过int型)! 数组实现 #include<cstdio> int p[10],k;//p数组用来保存n的质因子,int型n不会超过10个 void getp(int n){ k=0; for(int i=2;i*i<=n;i++){ if(n%i==0) p[k++]=i;

容斥原理学习(Hdu 4135,Hdu 1796)

题目链接Hdu4135 Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1412    Accepted Submission(s): 531 Problem Description Given a number N, you are asked to count the number of integers betwe

ACM学习历程—ZOJ 3868 GCD Expectation(莫比乌斯 || 容斥原理)

Description Edward has a set of n integers {a1, a2,...,an}. He randomly picks a nonempty subset {x1, x2,…,xm} (each nonempty subset has equal probability to be picked), and would like to know the expectation of [gcd(x1, x2,…,xm)]k. Note that gcd(x1, 

ACM学习历程—HDU 5072 Coprime(容斥原理)

Description There are n people standing in a line. Each of them has a unique id number. Now the Ragnarok is coming. We should choose 3 people to defend the evil. As a group, the 3 people should be able to communicate. They are able to communicate if

容斥原理

对容斥原理的描述 容斥原理是一种重要的组合数学方法,可以让你求解任意大小的集合,或者计算复合事件的概率. 描述 容斥原理可以描述如下: 要计算几个集合并集的大小,我们要先将所有单个集合的大小计算出来,然后减去所有两个集合相交的部分,再加回所有三个集合相交的部分,再减去所有四个集合相交的部分,依此类推,一直计算到所有集合相交的部分. 关于集合的原理公式 上述描述的公式形式可以表示如下:                  它可以写得更简洁一些,我们将B作为所有Ai的集合,那么容斥原理就变成了: 这个

【转载】【容斥原理】

转载自 http://www.cppblog.com/vici/archive/2011/09/05/155103.html 容斥原理(翻译) 前言: 这篇文章发表于http://e-maxx.ru/algo/inclusion_exclusion_principle,原文是俄语的.由于文章确实很实用,而且鉴于国内俄文资料翻译的匮乏,我下决心将其翻译之.由于俄语对我来说如同乱码,而用Google直接翻译中文的话又变得面目全非,所以只能先用Google翻译成英语,再反复读,慢慢理解英语的意思,实在

容斥原理 求M以内有多少个跟N是互质的

开始系统的学习容斥原理!通常我们求1-n中与n互质的数的个数都是用欧拉函数! 但如果n比较大或者是求1-m中与n互质的数的个数等等问题,要想时间效率高的话还是用容斥原理! 本题是求[a,b]中与n互质的数的个数,可以转换成求[1,b]中与n互质的数个数减去[1,a-1]与n互质的数的个数. #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define LL long

容斥原理 (转载)

前言: 这篇文章发表于http://e-maxx.ru/algo/inclusion_exclusion_principle,原文是俄语的.由于文章确实很实用,而且鉴于国内俄文资料翻译的匮乏,我下决心将其翻译之.由于俄语对我来说如同乱码,而用Google直接翻译中文的话又变得面目全非,所以只能先用Google翻译成英语,再反复读,慢慢理解英语的意思,实在是弄得我头昏脑胀.因此在理解文章意思然后翻译成中文的时候,中文都不知道如何表述了.而又由于我对容斥原理知识的匮乏,很可能有些地方我的表述是错误的

uva11806(容斥原理)

11806 - Cheerleaders Time limit: 2.000 seconds In most professional sporting events, cheerleaders play a major role in entertaining the spectators. Their roles are substantial during breaks and prior to start of play. The world cup soccer is no excep