首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

容斥定理怎么实现呢

2012-03-14 
请教大家容斥定理如何实现呢?http://acm.zju.edu.cn/show_problem.php?pid2836NumberPuzzle-------------

请教大家容斥定理如何实现呢?
http://acm.zju.edu.cn/show_problem.php?pid=2836

                                                    Number   Puzzle

--------------------------------------------

Time   limit:   1   Seconds       Memory   limit:   32768K      
Total   Submit:   967       Accepted   Submit:   213      

--------------------------------------------

Given   a   list   of   integers   (A1,   A2,   ...,   An),   and   a   positive   integer   M,   please   find   the   number   of   positive   integers   that   are   not   greater   than   M   and   dividable   by   any   integer   from   the   given   list.  

Input


The   input   contains   several   test   cases.  

For   each   test   case,   there   are   two   lines.   The   first   line   contains   N   (1   <=   N   <=   10)   and   M   (1   <=   M   <=   200000000),   and   the   second   line   contains   A1,   A2,   ...,   An(1   <=   Ai   <=   10,   for   i   =   1,   2,   ...,   N).  

Output

For   each   test   case   in   the   input,   output   the   result   in   a   single   line.  

Sample   Input

3   2
2   3   7
3   6
2   3   7


Sample   Output

1
4


大意是在1~M范围内求出们的倍数有几个,不要重复的.
这题是要用容斥定理的,这公式太复杂了,我只知道一种用2进制位移的方式去实现,还有别的好方法吗?   谢谢


[解决办法]
首先,更正一下。

我上次给的过程中的“然后,使A1, A2, ..., An两两互质。耗时O(n*n)。”是多余的。


下面是代码实现:

/**********************************
* Number Puzzle
*
* 容斥定理实现
*
* 编译环境: VC6.0
*
* 2007-5-12
***********************************/

#include <iostream>

using namespace std;

int TestBit( int n, int i )
{
return (n> > i)&1;
}

int gcd( int n, int m )
{
int s=n+m, temp;
n=(n> m)? n : m;
m=s-n;

while( m )
{
temp=m;
m=n%m;
n=temp;
}
return n;
}

int Count( int *list, int len, int m )
{
int i, j, Max=1 < <len;
int s=1, sum=0;
int g;

for( i=1; i <Max; ++i )
{
if(i&(i-1))
{
for( j=0; j <len; ++j )
{
if( TestBit( i, j ) )
{
g=gcd( list[j], s );
s=list[j]*s/g;
}
}
sum+=m/s;
}
}
return sum;

}

int main()
{
int n, m;
cin> > n> > m;
int *A=new int[n];
int i=0, temp;
while( i <n )
{
cin> > temp;
if( temp <=m )
A[i++]=temp;
else


--n;
}

int sum=0;
for( i=0; i <n; ++i )
sum+=m/A[i];

cout < <sum-Count(A, n, m ) < <endl;

delete []A;
return 1;
}

热点排行