HDU1796+容斥原理
给定n和m个数,询问在小于n的数中 有多少个能整除m中的某个数。。
容斥原理。
PS:注意64位整数!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 容斥原理 3 */ 4 #include<stdio.h> 5 #include<string.h> 6 #include<stdlib.h> 7 #include<iostream> 8 using namespace std; 9 typedef long long int64; 10 const int maxn = 24; 11 int64 num[ maxn ]; 12 int64 ans; 13 int n, m; 14 15 int gcd( int a,int b ){ 16 int r; 17 while( b ){ 18 r = a%b; 19 a = b; 20 b = r; 21 } 22 return a; 23 } 24 25 void dfs( int id,int Lcm,bool flag ){ 26 Lcm = Lcm*num[ id ] / gcd( Lcm,num[ id ] ); 27 if( flag ) ans += n/Lcm; 28 else ans -= n/Lcm; 29 for( int i=id+1;i<m;i++ ){ 30 dfs( i,Lcm,!flag ); 31 } 32 return; 33 } 34 35 int main(){ 36 //freopen( "in.txt","r",stdin ); 37 while( scanf("%d%d",&n,&m)==2 ){ 38 int cnt = 0; 39 for( int i=0;i<m;i++ ){ 40 //scanf("%d",&num[i]); 41 cin>>num[ i ]; 42 if( num[i] ) 43 num[ cnt++ ] = num[ i ]; 44 } 45 m = cnt; 46 ans = 0; 47 n --; 48 for( int i=0;i<m;i++ ){ 49 dfs( i,num[ i ],true ); 50 } 51 //printf("%d\n",ans); 52 cout<<ans<<endl; 53 } 54 return 0; 55 }
keep moving...