Bell(hdu4767+矩阵+中国剩余定理)

Bell

Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit  Status  Practice  HDU 4767
 

Description

What? MMM is learning Combinatorics!? 
Looks like she is playing with the bell sequence now: 
bell[n] = number of ways to partition of the set {1, 2, 3, ..., n} 

e.g. n = 3: 
{1, 2, 3} 
{1} {2 3} 
{1, 2} {3} 
{1, 3} {2} 
{1} {2} {3} 
so, bell[3] = 5 

MMM wonders how to compute the bell sequence efficiently. 
 

Input

T -- number of cases 
for each case: 
  n (1 <= n < 2^31) 
 

Output

for each case: 
  bell[n] % 95041567 
 

Sample Input

6
1
2
3
4
5
6
 

Sample Output

1
2
5
15
52
203
 
 

首先,我很高兴终于把这题给解出来了!!!自己有几个难点一直没想通,今天无聊的时候一想。然后思路莫名奇妙的顺了,一切都变的理所当然。。。然后,我趁热打铁,把思路一理,就被我A了!

题意:就是求n个数的非空集合的划分方法数;

例如n = 3

{1, 2, 3}

{1}  {2, 3}

{1, 2} {3}

{1, 3} {2}

{1} {2} {3}

所以Bell(3) = 5

给你一个n,求Bell(n) % 95041567的值

 

这道题涉及的知识比较多,,,本人觉得有一定的难度系数,没理解的,建议可以先从入门题刷起;

思路:

  首先必须了解一个概念贝尔数(来自维基百科)& Stirling数(不懂的点链接);

  其次,如果你不懂Stirling数,那么自己动手推一下,其实这个还是简单的,杭电有一题简单的题,可以练习下:

  http://acm.hdu.edu.cn/showproblem.php?pid=2512 相信很多同学都做过了,只是当时不知道是Stirling数,这里是第二类Stirling数;然后贝尔数呢,就是第二类Stirling数的和;

Bell(hdu4767+矩阵+中国剩余定理)_第1张图片

通过上面这个公式,我们可以利用矩阵计算大于n的贝尔数,方法是利用中国剩余定理,结合欧几里德和同余方程;首先我们输入n(假设,n>p,p是95041567的质因子,eg:n=50),对n<50的Bell数进行预处理,构造一个p*p的矩阵;

Bell(hdu4767+矩阵+中国剩余定理)_第2张图片

利用公式求出,他们的余数存入数组at[i];质因子m[5]={31,37,41,43,47};利用中国剩余定理;求得余数!

 

转载请注明出处:寻找&星空の孩子   

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4767


#include
#include
#define LL long long
#define mod 95041567
#define MM 50

int m[5]={31,37,41,43,47};
int Sti[MM][MM],bell[MM][MM];
int at[5];//各项余数

void stirling2()
{
    memset(Sti,0,sizeof(Sti));
    Sti[0][0]=1;
    for(int i=1;i<=MM;i++)
    {
        for(int j=1;j<=i;j++)
        {
            Sti[i][j]=(int)(Sti[i-1][j-1]+((LL)j*(LL)Sti[i-1][j])%mod)%mod;
        }
    }
}
void init()
{
    stirling2();
    for(int i=0;i<5;i++)
    {
        bell[i][0]=1;
        for(int j=1;j>=1;
        a=multiply(a,a,M);
    }
    return res;
}

int work(int n,int M,int k)
{
    Matrix per;//基础矩阵;
    memset(per.mat,0,sizeof(per.mat));
    per.mat[0][M-1]=1;

    for(int i=1;i


时间过的好快,居然要期末考了,,,在学校的日子也不多了,aking2015......为了我们共同的梦!fighting!



你可能感兴趣的:(ACM-矩阵,ACM-中国剩余定理,ACM-扩展欧几里德,ACM-数论,ACM-HDUOJ(杭电),ACM--数论专题,hdu4767,bell数,中国剩余定理,扩展欧几里德,矩阵快速幂)