Bell(hdu4767+矩阵+中国剩余定理+bell数+Stirling数+欧几里德)
Bell
Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Description
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
for each case:
n (1 <= n < 2^31)
Output
bell[n] % 95041567
Sample Input
Sample Output
首先,我很高兴终于把这题给解出来了!!!自己有几个难点一直没想通,今天无聊的时候一想。然后思路莫名奇妙的顺了,一切都变的理所当然。。。然后,我趁热打铁,把思路一理,就被我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[]={,,,,};
int Sti[MM][MM],bell[MM][MM];
int at[];//各项余数 void stirling2()
{
memset(Sti,,sizeof(Sti));
Sti[][]=;
for(int i=;i<=MM;i++)
{
for(int j=;j<=i;j++)
{
Sti[i][j]=(int)(Sti[i-][j-]+((LL)j*(LL)Sti[i-][j])%mod)%mod;
}
}
}
void init()
{
stirling2();
for(int i=;i<;i++)
{
bell[i][]=;
for(int j=;j<m[i];j++)
{
bell[i][j]=;
for(int k=;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,,sizeof(c.mat));
for(int i=;i<M;i++)
{
for(int j=;j<M;j++)
{
if(a.mat[i][j]==)continue;
for(int k=;k<M;k++)
{
if(b.mat[j][k]==)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=;i<M;i++)
{
for(int j=;j<M;j++)
res.mat[i][j]=(i==j);
} while(n)
{
if(n&) res=multiply(res,a,M);
n>>=;
a=multiply(a,a,M);
}
return res;
} int work(int n,int M,int k)
{
Matrix per;//基础矩阵;
memset(per.mat,,sizeof(per.mat));
per.mat[][M-]=; for(int i=;i<M;i++)
{
per.mat[i][i]=per.mat[i][i-]=;
} Matrix tmp=quickmod(per,n/(M-),M); int ans[MM];
for(int i=;i<M;i++)
{
ans[i]=;
for(int j=;j<M;j++)
{
ans[i]=(ans[i]+bell[k][j]*tmp.mat[i][j])%M;
}
}
return ans[n%(M-)];
}
void exgcd(int a,int b,int& d,int& x,int &y)
{
if(!b){d=a;x=;y=;}
else
{
exgcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
int China(int r)
{
int Mc=;
int Mi,d,x,y,as=;
for(int i=;i<r;i++)
{
Mc*=m[i];
}
for(int i=;i<r;i++)
{
Mi=Mc/m[i];
exgcd(Mi,m[i],d,x,y);
as=(as+Mi*x*at[i])%Mc;
}
if(as<) as+=Mc;
return as;
}
int main()
{
int T,n;
scanf("%d",&T); init();
while(T--)
{
scanf("%d",&n);
for(int i=;i<;i++)
{
at[i]=work(n,m[i],i);
}
int sol=China();
printf("%d\n",sol);
} return ;
}
时间过的好快,居然要期末考了,,,在学校的日子也不多了,aking2015......为了我们共同的梦!fighting!
Bell(hdu4767+矩阵+中国剩余定理+bell数+Stirling数+欧几里德)的更多相关文章
- HDU 4767 Bell(矩阵+中国剩余定理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4767 题意:给出n.求n有多少种划分集合的方式,即bell(n) 思路: #include <i ...
- 斯特灵数 (Stirling数)
@维基百科 在组合数学,Stirling数可指两类数,都是由18世纪数学家James Stirling提出的. 第一类 s(4,2)=11 第一类Stirling数是有正负的,其绝对值是个元素的项目分 ...
- 2013长春网赛1009 hdu 4767 Bell(矩阵快速幂+中国剩余定理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4767 题意:求集合{1, 2, 3, ..., n}有多少种划分情况bell[n],最后结果bell[ ...
- Stirling数,Bell数,Catalan数,Bernoulli数
组合数学的实质还是DP,但是从通式角度处理的话有利于FFT等的实现. 首先推荐$Candy?$的球划分问题集合: http://www.cnblogs.com/candy99/p/6400735.ht ...
- Bell数和Stirling数
前面说到了Catalan数,现在来了一个Bell数和Stirling数.什么是Bell数,什么是Stirling数呢?两者的关系如何,有用于解决什么算法问题呢? Bell数是以Bell这个人命名的,组 ...
- (转) [组合数学] 第一类,第二类Stirling数,Bell数
一.第二类Stirling数 定理:第二类Stirling数S(p,k)计数的是把p元素集合划分到k个不可区分的盒子里且没有空盒子的划分个数. 证明:元素在哪些盒子并不重要,唯一重要的是各个盒子里装的 ...
- 贝尔数(来自维基百科)& Stirling数
贝尔数 贝尔数以埃里克·坦普尔·贝尔(Eric Temple Bell)为名,是组合数学中的一组整数数列,开首是(OEIS的A000110数列): Bell Number Bn是基数为n的集合 ...
- FJNU2018低程A 逃跑路线(Lucas + 中国剩余定理 + LGV定理)题解
题目描述 n个人在w*h的监狱里面想要逃跑,已知他们的同伙在坐标(bi,h)接应他们,他们现在被关在(ai,1)现在他们必须要到同伙那里才有逃出去的机会,这n个人又很蠢只会从(x,y)->(x+ ...
- 第二类Stirling数
第二类斯特林数 第二类Stirling数:S2(p, k) 1.组合意义:第二类Stirling数计数的是把p个互异元素划分为k个非空集合的方法数 2.递推公式: S2(0, 0) = 1 S2(p, ...
随机推荐
- 实战C++对象模型之成员函数调用
先说结论:C++的类成员函数和C函数实质是一样的,只是C++类成员函数多了隐藏参数this. 通过本文的演示,可以看见这背后的一切,完全可C函数方式调用C++类普通成员函数和C++类虚拟成员函数. 为 ...
- HTML之<meta>使用和说明
关于<meta>,我们都不陌生,随意打开一个网页查看源代码就可以看到<head>里出现它的身影. 简单来说,<meta>是描述 HTML 文档的元数据.例如网页描述 ...
- 如何使用Visual Studio 2017调试.net库源代码
在Visual Studio 2017按如下步骤设置: 1.取消选中(工具 - >选项 - >调试 - >仅我的代码)复选框.2.确保设置了(工具 - >选项 - >调试 ...
- Microsoft在8月7号发布的帮助文档更新中,HelpLibrary2安装Cab文档包出现签名问题
在VS 2017 8月2号发布15.7.6版本后,在8月7号推送了helpview程序中的绝大部分更新文档,在本次推送中多数Cab文件出现了无法进行安装的签名问题, 不论是单个下载,还是删除本地所有已 ...
- 数据库路由中间件MyCat - 源代码篇(7)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 3. 连接模块 3.4 FrontendConnection前端连接 构造方法: public Fronte ...
- 2019-4-26 css学习笔记
CSS简介:Cascading Style Sheets(层叠样式表)的缩写,它是一种用来表现HTML或XML等文件样式的计算机语言. CSS的作用:是定义网页外观(例如,字体.背景.文本.位置.布局 ...
- 第二十九节:Java基础知识-类,多态,Object,数组和字符串
前言 Java基础知识-类,多态,Object,数组和字符串,回顾,继承,类的多态性,多态,向上转型和向下转型,Object,数组,多维数组,字符串,字符串比较. 回顾 类的定义格式: [类的修饰符] ...
- Java面试集合(二)
前言 大家好,给大家带来Java面试集合(二)的概述,希望你们喜欢 二 1.请问线程有哪些状态? 新建状态(New) 就绪状态(Runnable) 运行状态(Running) 阻塞状态(Blocked ...
- react小知识2
概述 这是我学习react的过程中,学到的一些简便写法,都是利用了es6的特性,记录下来供以后开发时参考,相信对其他人也有用. 参考资料:dva.js 知识导图 析构 我们也可以析构传入的函数参数. ...
- Swift5 语言指南(八) 函数
函数是执行特定任务的自包含代码块.您为函数指定了一个标识其功能的名称,此名称用于“调用”函数以在需要时执行其任务. Swift的统一函数语法足够灵活,可以表达从没有参数名称的简单C风格函数到具有每个参 ...
