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数的和;

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

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

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

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

#include<stdio.h>
#include<string.h>
#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<m[i];j++)
        {
            bell[i][j]=0;
            for(int k=1;k<=j;k++)
            {
                bell[i][j]=(bell[i][j]+Sti[j][k])%m[i];
            }
//            printf("%d\t%d\n",j,bell[i][j]);
        }
    }
}
struct Matrix
{
    int mat[MM][MM];
};

Matrix multiply(Matrix a,Matrix b,int M)
{
    Matrix c;
    memset(c.mat,0,sizeof(c.mat));
    for(int i=0;i<M;i++)
    {
        for(int j=0;j<M;j++)
        {
            if(a.mat[i][j]==0)continue;
            for(int k=0;k<M;k++)
            {
                if(b.mat[j][k]==0)continue;
                c.mat[i][k]=(c.mat[i][k]+a.mat[i][j]*b.mat[j][k])%M;
            }
        }
    }
    return c;
}
Matrix quickmod(Matrix a,int n,int M)
{
    Matrix res;

    for(int i=0;i<M;i++)
    {
        for(int j=0;j<M;j++)
            res.mat[i][j]=(i==j);
    }

    while(n)
    {
        if(n&1) res=multiply(res,a,M);
        n>>=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<M;i++)
    {
            per.mat[i][i]=per.mat[i][i-1]=1;
    }

    Matrix tmp=quickmod(per,n/(M-1),M);

    int ans[MM];
    for(int i=0;i<M;i++)
    {
        ans[i]=0;
        for(int j=0;j<M;j++)
        {
            ans[i]=(ans[i]+bell[k][j]*tmp.mat[i][j])%M;
        }
    }
    return ans[n%(M-1)];
}
void exgcd(int a,int b,int& d,int& x,int &y)
{
    if(!b){d=a;x=1;y=0;}
    else
    {
        exgcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}
int China(int r)
{
    int Mc=1;
    int Mi,d,x,y,as=0;
    for(int i=0;i<r;i++)
    {
        Mc*=m[i];
    }
    for(int i=0;i<r;i++)
    {
        Mi=Mc/m[i];
        exgcd(Mi,m[i],d,x,y);
        as=(as+Mi*x*at[i])%Mc;
    }
    if(as<0) as+=Mc;
    return as;
}
int main()
{
    int T,n;
    scanf("%d",&T);

    init();
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0;i<5;i++)
        {
            at[i]=work(n,m[i],i);
        }
        int sol=China(5);
        printf("%d\n",sol);
    }

    return 0;
}

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

时间: 2024-10-19 02:32:17

Bell(hdu4767+矩阵+中国剩余定理)的相关文章

Bell(hdu4767+矩阵+中国剩余定理+bell数+Stirling数+欧几里德)

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 part

hdu 4878 ZCC loves words(AC自动机+dp+矩阵快速幂+中国剩余定理)

hdu 4878 ZCC loves words(AC自动机+dp+矩阵快速幂+中国剩余定理) 题意:给出若干个模式串,总长度不超过40,对于某一个字符串,它有一个价值,对于这个价值的计算方法是这样的,设初始价值为V=1,假如这个串能匹配第k个模式串,则V=V*prime[k]*(i+len[k]),其中prime[k]表示第k个素数,i表示匹配的结束位置,len[k]表示第k个模式串的长度(注意,一个字符串可以多次匹配同意个模式串).问字符集为'A'-'Z'的字符,组成的所有的长为L的字符串,

HDU 5768 Lucky7 (中国剩余定理+容斥)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5768 给你n个同余方程组,然后给你l,r,问你l,r中有多少数%7=0且%ai != bi. 比较明显的中国剩余定理+容斥,容斥的时候每次要加上个(%7=0)这一组. 中间会爆longlong,所以在其中加上个快速乘法(类似矩阵快速幂).因为普通的a*b是直接a个b相加,很可能会爆.但是你可以将b拆分为二进制来加a,这样又快又可以防爆. 1 //#pragma comment(linker, "/S

Hello Kiki(中国剩余定理——不互质的情况)

Hello Kiki Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 247 Accepted Submission(s): 107   Problem Description One day I was shopping in the supermarket. There was a cashier counting coins serio

Biorhythms(中国剩余定理)

Biorhythms Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 127339   Accepted: 40342 Description Some people believe that there are three cycles in a person's life that start the day he or she is born. These three cycles are the physical,

lightoj 1319 - Monkey Tradition (中国剩余定理)

1319 - Monkey Tradition PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB In 'MonkeyLand', there is a traditional game called "Bamboo Climbing". The rules of the game are as follows: 1)       There are N monkeys who play

HDU 5446 Unknown Treasure(lucas + 中国剩余定理 + 模拟乘法)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5446 题目大意:求C(n, m) % M, 其中M为不同素数的乘积,即M=p1*p2*...*pk, 1≤k≤10.1≤m≤n≤10^18. 分析: 如果M是素数,则可以直接用lucas定理来做,但是M不是素数,而是素数的连乘积.令C(n, m)为 X ,则可以利用lucas定理分别计算出 X%p1,X%p2, ... , X % pk的值,然后用中国剩余定理来组合得到所求结果. 比较坑的地方是,

UVA 11754 Code Feat (枚举,中国剩余定理)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud C Code Feat   The government hackers at CTU (Counter-Terrorist Unit) have learned some things about the code, but they still haven't quite solved it.They know it's a single, strictly positive

hdu1573X问题(不互素的中国剩余定理)

X问题 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3295    Accepted Submission(s): 1068 Problem Description 求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], -, X mo