首页 > 代码库 > [容斥原理] hdu 1796 How many integers can you find
[容斥原理] hdu 1796 How many integers can you find
题意:
给一个N,然后给M个数,问1~N-1里面有多少个数能被这M个数中一个或多个数整除。
思路:
首先要N--
然后对于每个数M 其实1~N-1内能被其整除的 就是有(N-1)/M[i]个
但是会出现重复 比如 样例 6就会被重复算
这时候我们就需要容斥原理了
加上一个数的减去两个数的。。
这里要注意了 两个数以上的时候 是求LCM而不是简单的相乘!
代码:
[cpp] view plaincopy
- #include "stdio.h"
- #include "string.h"
- #include "math.h"
- #include "iostream"
- #include "cstdlib"
- #include "algorithm"
- #include "queue"
- using namespace std;
- int a[12];
- int used[12],b[12];
- int n,m;
- int gcd(int a,int b)
- {
- return b==0?a:gcd(b,a%b);
- }
- int lcm(int k)
- {
- int ans=b[0];
- for(int i=1;i<k;i++)
- {
- int tep=gcd(ans,b[i]);
- ans=ans/tep*b[i];
- }
- return ans;
- }
- __int64 dfs(int kk,int x,int lit)
- {
- __int64 ans=0;
- if(x==lit)
- {
- int tep;
- tep=lcm(x);
- return n/tep;
- }
- for(int i=kk+1;i<m;i++)
- {
- if(a[i]==0) continue;
- if(used[i]) continue;
- used[i]=1;
- b[x]=a[i];
- ans+=dfs(i,x+1,lit);
- used[i]=0;
- }
- return ans;
- }
- int main()
- {
- while(scanf("%d%d",&n,&m)!=-1)
- {
- n--;
- for(int i=0;i<m;i++) scanf("%d",&a[i]);
- __int64 ans=0;
- for(int i=1;i<=m;i++)
- {
- // printf("%d\n",dfs(-1,0,i));
- memset(used,0,sizeof(used));
- if(i%2==0) ans-=dfs(-1,0,i);
- else ans+=dfs(-1,0,i);
- }
- printf("%I64d\n",ans);
- }
- return 0;
- }
[容斥原理] hdu 1796 How many integers can you find
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。