HDU4767 Bell 中国剩余定理 贝尔数 第二类斯特灵数
来源:互联网 发布:淘宝我的提问在哪里看 编辑:程序博客网 时间:2024/05/11 09:36
这道题要是出在现场赛 估计做出的人要少很多很多,要查阅很多资料才做的出来,至少对于我这个菜狗来说 必须要查资料
http://zh.wikipedia.org/wiki/%E6%96%AF%E7%89%B9%E7%81%B5%E6%95%B0
首先要了解第二类斯特灵数,还有贝尔数,
接下来是解题的关键:
若p为任意质数,则有Bell(n+p) = Bell(n) + Bell(n+1) (mod p);
我们来分解题目给的模的数 95041567=31*37*41*43*47,这五个数都是素数,所以可以用上述的式子来解题目,同时又因为 这五个数两两互素,所以可以利用中国剩余定理来解 x=a1(mod m1)这个同余方程组,求出 mod(m1*m2...*mi)d的值,这样就可以得到答案了
但是在使用中国剩余定理之前 我们要求出 Bell(n)%各个素数的 值,这里需要矩阵快速幂
举个例子 若 素数为5此时可以构造这样一个矩阵
0 1 0 0 0
0 1 1 0 0
0 0 1 1 0
0 0 0 1 1
1 0 0 0 1
再列举一个3的矩阵,你就会发现一定的规律,这样就可以求出 Bell(n)%各个素数的值了
#include<iostream>#include<cstdio>#include<list>#include<algorithm>#include<cstring>#include<string>#include<queue>#include<stack>#include<map>#include<vector>#include<cmath>#include<memory.h>#include<set>#define ll long long#define LL __int64#define eps 1e-8//const ll INF=9999999999999;#define inf 0xfffffffusing namespace std;//vector<pair<int,int> > G;//typedef pair<int,int> P;//vector<pair<int,int>> ::iterator iter;////map<ll,int>mp;//map<ll,int>::iterator p;////vector<int>G[30012];int MOD[5]={31,37,41,43,47};int a[12][62][62],b[12][62];int c[62];int n;void getstrling()//获取第二类斯特灵数,可以看维基百科{for(int i=0;i<5;i++)a[i][0][0]=1;for(int i=1;i<=50;i++){for(int j=0;j<5;j++)a[j][i][1]=1;for(int j=1;j<=i;j++){for(int k=0;k<5;k++)a[k][i][j]=(a[k][i-1][j-1]+j*a[k][i-1][j])%MOD[k];}for(int j=0;j<5;j++){b[j][i]=0;for(int k=1;k<=i;k++)b[j][i]=(b[j][i]+a[j][i][k])%MOD[j];}}}int Matrixquick(int id,int mod){int x[62],xx[62],y[62][62],yy[62][62];int len=MOD[id]+1;for(int i=1;i<=len+1;i++)for(int j=1;j<=len+1;j++)y[i][j]=0;for(int i=1;i<len;i++)y[i+1][i]=1;y[2][len]=y[3][len]=1;for(int i=1;i<=len;i++)x[i]=b[id][i];//构造矩阵的过程,这个矩阵有点规律的,if(MOD[id]>=n)return x[n];int tempn=n-1;while(tempn)//再写一个函数反而觉得麻烦 直接讲快速幂套在里面了{if(tempn&1){for(int i=1;i<=len;i++){xx[i]=0;for(int j=1;j<=len;j++)xx[i]+=x[j]*y[j][i];}for(int i=1;i<=len;i++)x[i]=xx[i]%mod;}for(int i=1;i<=len;i++){for(int j=1;j<=len;j++){yy[i][j]=0;for(int k=1;k<=len;k++)yy[i][j]+=y[i][k]*y[k][j];yy[i][j]%=mod;}}for(int i=1;i<=len;i++)for(int j=1;j<=len;j++)y[i][j]=yy[i][j];tempn>>=1;}return x[1];}int exgcd(int a,int &x,int b,int &y){if(b==0){x=1;y=0;return a;}int r=exgcd(b,x,a%b,y);int tmp=x;x=y;y=tmp-a/b*y;return r;}int china()//中国剩余定理{int M=1;int ans=0;for(int i=0;i<5;i++)M*=MOD[i];for(int i=0;i<5;i++){int Mi=M/MOD[i];int x0,y0;int gcd=exgcd(Mi,x0,MOD[i],y0);ans=(ans+x0*Mi*c[i])%M;}return (ans+M)%M;}int main(void){getstrling();int t;scanf("%d",&t);while(t--){scanf("%d",&n);for(int i=0;i<5;i++)c[i]=Matrixquick(i,MOD[i]);int ans=china();printf("%d\n",ans);}}
- HDU4767 Bell 中国剩余定理 贝尔数 第二类斯特灵数
- Hdu4767 Bell (贝尔数 中国剩余定理 构造矩阵)
- 贝尔数 hdu4767 (矩阵快速幂+中国剩余定理+bell数+Stirling数+欧几里德)
- Bell(hdu4767+矩阵+中国剩余定理)
- Bell数+中国剩余定理
- HDU 4767 Bell (贝尔数 中国剩余定理 构造矩阵) ★ ★
- HDU 4767 Bell (中国剩余定理)
- HDU 4767 Bell (中国剩余定理)
- hdu 4746 Bell 中国剩余定理+矩阵乘法+第二类斯特林数 (2013网络赛)
- 贝尔(Bell)数
- HDU4767(待做)&&HDU2512 【Bell数】
- hdu 4767 bell 中国剩余定理+矩阵快速幂
- Bell(矩阵快速幂+中国剩余定理)
- 中国剩余定理-数硬币
- Bell - HDU 4767 贝尔数
- 中国剩余定理模版【中国剩余定理】
- 中国剩余定理
- 中国剩余定理
- java中Class.forName的含义
- 黑马程序员 -->齐头并进完成任务--多线程(下)
- Android日志系统Logcat源代码简要分析
- safari 和Firefox js中不一致的敌方
- php 网页数据抓取 简单实例
- HDU4767 Bell 中国剩余定理 贝尔数 第二类斯特灵数
- Web中调用WinForm简介 (ie中调用用户控件)
- 二十岁出头的时候上,你一无所有,你拥有一切
- base64转码
- goagent升级步骤
- Android应用程序框架层和系统运行库层日志系统源代码分析
- 计算多个集合的组合排列个数
- javascript中return的作用
- 一口一口吃掉Hibernate(六)——多对多关联映射