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

题意:求集合{1, 2, 3, ..., n}有多少种划分情况bell[n],最后结果bell[n] mod 95041567.

分析:首先了解三个概念:贝尔数   第二类斯特灵数   中国剩余定理

贝尔数是指基数为n的集合的划分方法的数目。

贝尔数适合递推公式:

每个贝尔数都是"第二类Stirling数"的和

贝尔数满足两个公式:(p为质数)

            1) B[n+p] = B[n] + B[n+1] (mod p) ;

            2) B[p^m+n] = m*B[n] + B[n+1] (mod p) .

将95041567质因数分解发现,95041567 = 31*37*41*43*47

所以B[n]%95041567可以分解为 B[n]%p(p=31,41,43,47),

我们可以先求出B[n] mod p[i]的值a[i],这样问题就转化为 X=a[i](mod p[i]),

很明显这是几个一次同余方程,最后用中国剩余定理合并就可以了。

那要怎么求B[n]%p[i]呢?

利用上面的公式(1),我们发现这是 一个递推式,所以可以利用矩阵法来求解。

我们可以构造一个大小为当前p*p的矩阵。

这样我们就可以求出任意的B[n]了

我们可以先用贝尔数递推公式求出前50个贝尔数,因为p[i]<50,所以对于大于p[i]的贝尔数,由上面的矩阵法可以求得。

比如:| 1 1 0 0 .... 0 0 |      |   B[1]  |      | B[1+p] |

| 0 1 1 0 .... 0 0 |      |   B[2]  |      | B[2+p] |

| 0 0 1 1 .... 0 0 |      |   B[3]  |      | B[3+p] |

| ....  .... .... ....  |  *  |   .....   |  =  |    .....   |

| 0 0 0 0 .... 1 1 |      | B[p-1] |      | B[2p-1]|

| 1 1 0 0 .... 0 1 |      |   B[p]  |      | B[2p]   |

若n=i+p,则只需求一次A*C=D,然后输出D[n-p]即D[i]就行了,

比如p[0]=31,如要求B[32]=B[1+31],只需求一次A*C=D,然后输出D[1],求B[51]则输出D[20]。

那么

若n=i+p^m,这只需求A^m*C=D,然后输出D[i]即可

到此算法结束

总结一下:

先用贝尔数递推公式求出前50个贝尔数,然后用矩阵快速幂分别求出bell[n]%p[i]赋给a[i],然后用中国剩余定理合并结果就可以求出bell[n]%95041567了。

AC代码如下:

 #include<stdio.h>
#include<string.h>
#define LL __int64
int w[]={,,,,};
LL c[][][],bell[][];
LL a[];
struct Matrix{
LL m[][];
};
void init()
{
int i,j,k;
for(k=;k<;k++)
{
c[][][k]=;
for(i=;i<;i++) //c[i][j][k] 表示c(i,j)%w[k]
{
c[i][][k]=c[i][i][k]=;
for(j=;j<i;j++)
c[i][j][k]=(c[i-][j-][k]+c[i-][j][k])%w[k];
}
}
// 预处理出前50项分别取模的大小
for(k=;k<;k++)
{
bell[][k]=;
for(i=;i<;i++)
{
bell[i][k]=;
for(j=;j<i;j++)
{
bell[i][k]=(bell[i][k]+c[i-][j][k]*bell[j][k])%w[k];
}
}
}
}
LL exgcd(LL a,LL b,LL &x,LL &y) //扩展欧几里得
{
if(b==)
{
x=; y=;
return a;
}
LL d=exgcd(b,a%b,x,y);
LL t=x;
x=y;
y=t-a/b*y;
return d;
}
LL CRT(int k) //中国剩余定理
{
LL i,N=,ans=;
LL t,x,y,d;
for(i=;i<k;i++)
N*=w[i];
for(i=;i<k;i++)
{
t=N/w[i];
d=exgcd(t,w[i],x,y);
ans=(ans+x*t*a[i])%N;
}
return (ans+N)%N;
}
Matrix mul(Matrix x,Matrix y,int n,int mod) //矩阵乘法
{
int i,j,k;
Matrix tmp;
memset(tmp.m,,sizeof(tmp.m));
for(i=;i<=n;i++)
for(j=;j<=n;j++)
for(k=;k<=n;k++)
{
tmp.m[i][j]+=(x.m[i][k]*y.m[k][j])%mod;
tmp.m[i][j]%=mod;
}
return tmp;
}
Matrix quickpow(Matrix res,Matrix A,int k,int n,int mod) //矩阵快速幂模
{
int i;
memset(res.m,,sizeof(res.m));
for(i=;i<=n;i++)
res.m[i][i]=;
while(k)
{
if(k&)
res=mul(res,A,n,mod);
A=mul(A,A,n,mod);
k>>=;
}
return res;
}
LL BellNumber(int n,int p) //求bell[n][p]即bell[n]%w[p]
{
int i;
if(n<)
return bell[n][p];
Matrix A,origin,ans;
memset(A.m,,sizeof(A.m));
memset(origin.m,,sizeof(origin.m));
for(i=;i<w[p];i++)
A.m[i][i]=A.m[i][i+]=;
A.m[w[p]][]=;
A.m[w[p]][]=;
A.m[w[p]][w[p]]=;
for(i=;i<=w[p];i++)
origin.m[i][]=bell[i][p];
LL cnt=n/w[p];
n=n-w[p]*cnt;
Matrix res;
res=quickpow(res,A,cnt,w[p],w[p]);
ans=mul(res,origin,w[p],w[p]);
return ans.m[n][];
}
void solve(int n)
{
int i;
for(i=;i<;i++)
a[i]=BellNumber(n,i); //bell[n]mod各个质数的值
LL ans=CRT();
printf("%I64d\n",ans);
}
int main()
{
int t,n;
init();
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
solve(n);
}
return ;
}

2013长春网赛1009 hdu 4767 Bell(矩阵快速幂+中国剩余定理)的更多相关文章

  1. Bell(矩阵快速幂+中国剩余定理)

    Bell Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status  ...

  2. 2013长春网赛1005 hdu 4763 Theme Section(kmp应用)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4763 题意:给出一个字符串,问能不能在该串的前中后部找到相同的子串,输出最长的字串的长度. 分析:km ...

  3. 2013长春网赛1001 hdu 4759 Poker Shuffle

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4759 题意:有一堆2^n的牌,牌原先按(1,2,....k)排序,每一次洗牌都将牌分成两种情况:(1, ...

  4. 2013长春网赛1004 hdu 4762 Cut the Cake

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4762 题意:有个蛋糕,切成m块,将n个草莓放在上面,问所有的草莓放在同一块蛋糕上面的概率是多少.2 & ...

  5. 2013长春网赛1010 hdu 4768 Flyer

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4768 题意:有n个社团发传单,每个社团发给编号为A_i, A_i+C_i,A_i+2*C_i,…A_i ...

  6. 2013长春网赛 1006 hdu 4764 Stone(巴什博弈)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4764 题意:Tang 和 Jiang 玩一个游戏,轮流写下一个数,Tang先手,第一次Tang只能写[ ...

  7. HDU.2640 Queuing (矩阵快速幂)

    HDU.2640 Queuing (矩阵快速幂) 题意分析 不妨令f为1,m为0,那么题目的意思为,求长度为n的01序列,求其中不含111或者101这样串的个数对M取模的值. 用F(n)表示串长为n的 ...

  8. HDU 5667 构造矩阵快速幂

    HDU 5667 构造矩阵快速幂 题目描述 解析 我们根据递推公式 设 则可得到Q的指数关系式 求Q构造矩阵 同时有公式 其中φ为欧拉函数,且当p为质数时有 代码 #include <cstdi ...

  9. HDU 6185 Covering 矩阵快速幂

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6185 题意:用 1 * 2 的小长方形完全覆盖 4 * n的矩形有多少方案. 解法:小范围是一个经典题 ...

随机推荐

  1. jsp操作javabean

    一:介绍 javabean: java语言编写的一个可重用的组件. 狭义上来说就是我们编写的一个普通的java类,例如:User... javabean规范: 1.必须是一个公共具体的类:public ...

  2. 所谓的液晶屏驱动IC是单独的IC还是在屏内就集成

    所谓的液晶屏驱动IC是单独的IC还是在屏内就集成 时间:2016-12-05    作者:admin   其实无论什么液晶屏,想要正常工作必须包括两个人:玻璃屏+驱动IC:但是现在有一些液晶厂商他们不 ...

  3. allegro中Autosilk top, Silkscreen top 和Assembly top三个什么区别(转)

    allegro中Autosilk top, Silkscreen top 和Assembly top三个什么区别(转) Autosilk top, Silkscreen top 和Assembly t ...

  4. 搭建HBase的本地模式、伪分布式、全分布式和HA模式

    一.安装HBase: 我这里选择的是hbase-1.3.1-bin.tar.gz版本解压HBase: tar -zxvf hbase-1.3.1-bin.tar.gz -C ~/training 配置 ...

  5. 20155209 林虹宇 Exp9 Web安全基础

    Exp9 Web安全基础 XSS 1.Phishing with XSS 跨站脚本攻击,在表单中输入超文本代码 在网页中形成一个自制的登陆表单,然后将结果反馈到自己的主机上. 攻击成功 2.Store ...

  6. java 锁白话

    一.锁 1.可见性: 定义:数据对所有线程可见 原因:cpu操作数据时会把数据读取到内存中去,可以理解为值做了备份,但是备份数据和原始数据在后续操作中不一定一致 实现:java使用volite关键字来 ...

  7. POJ2531&&1416&&2676&&1129

    搜索专题的最后一块了,也告别了这些老的东西了 接下来就是些全新的内容了啊! 这次的标签是简单搜索技巧和剪枝,也就是优化爆搜 当然,像Dancing links这样的玄学操作还是没有的 2531 题意: ...

  8. Bluedroid协议栈BTU线程处理HCI数据流程分析

    在蓝牙enable的过程中会进行多个线程的创建以及将线程与队列进行绑定的工作.该篇文章主要分析一下处理hci数据这个 线程. void BTU_StartUp(void) { ... btu_bta_ ...

  9. python的多继承关系

    python和C++一样,支持多继承.概念虽然容易,但是困难的工作是如果子类调用一个自身没有定义的属性,它是按照何种顺序去到父类寻找呢,尤其是众多父类中有多个都包含该同名属性. class P1 #( ...

  10. cookie提取dex文件

    有时候在java层能获取dex文件的cookie,但是在java不能从cookie得到dex,如果想要获取只能通过jni在C层实现,具体实现代码如下(nexus手机4.4系统) static void ...