bzoj 3501 PA2008 Cliquers Strike Back——贝尔数

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3501

用贝尔三角形 p^2 地预处理 p 以内的贝尔数。可以模(mod-1)(它是每个分解下的质因子的倍数,所以不影响分开算的时候)。

用公式:\( Bell[n+p^{m}]=m*Bell[n]+Bell[n+1] (mod p) \)  \( Bell[n+p]=Bell[n]+Bell[n+1] (mod p) \)  把 n 看成 p 进制,O( p^2 * log m ) 地算。

  大概就是从低位走到高位。一开始自己的 b 数组是 Bell[ 0 ] ~ Bell[ p ] ;枚举每一个 p 进制位(从第二位,即 p1 开始),在该位上枚举从1到d[ i ],做一次让角标 + pi 的操作;

  这样做完,自己的 b 数组存的就是 Bell[ d[m-1]*pm-1+d[m-2]*pm-2+...+0 ] ~ Bell[ d[m-1]*pm-1+d[m-2]*pm-2+...+p ] 的值。只要输出 b[ d[0] ] 就行了。

借鉴Claris的模板。http://www.cnblogs.com/clrs97/p/4714467.html

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int mod=999999599,M=mod-1,N=7283;
ll n,m; int p[5]={2,13,5281,7283},ans,f[N+5],s[2][N+5];
void upd(int &x,int md){x>=md?x-=md:0;}
int pw(int x,int k,int md)
{int ret=1;while(k){if(k&1)ret=(ll)ret*x%md;x=(ll)x*x%md;k>>=1;}return ret;}
int calc(ll n,int p)
{
  if(n<=N)return f[n]%p;
  int b[N+5],c[N+5],d[65],lm=0;
  for(int i=0;i<=p;i++)b[i]=f[i]%p;
  while(n)d[lm++]=n%p,n/=p;
  for(int i=1;i<lm;i++)
    for(int j=1;j<=d[i];j++)
      {
    for(int k=0;k<p;k++)c[k]=(i*b[k]+b[k+1])%p;
    c[p]=c[0]+c[1];upd(c[p],p);
    for(int k=0;k<=p;k++)b[k]=c[k];
      }
  return b[d[0]];
}
int main()
{
  int i,j;bool fx;
  f[0]=s[1][0]=1;
  for(i=1,fx=0;i<=N;i++,fx=!fx)//i=1,len=2(0~i)
    for(f[i]=s[fx][0]=s[!fx][i-1],j=1;j<=i;j++)
      s[fx][j]=s[!fx][j-1]+s[fx][j-1],upd(s[fx][j],M);//%M?its lcm so ok
  scanf("%lld%lld",&n,&m);
  for(i=0;i<4;i++)
    ans=(ans+(ll)(M/p[i])*pw(M/p[i],p[i]-2,p[i])%M*calc(n,p[i]))%M;
  printf("%d\n",pw(m%mod,ans,mod));
  return 0;
}

原文地址:https://www.cnblogs.com/Narh/p/10066825.html

时间: 2024-10-14 02:42:01

bzoj 3501 PA2008 Cliquers Strike Back——贝尔数的相关文章

BZOJ3501 : PA2008 Cliquers Strike Back

\[\begin{eqnarray*}ans&=&m^{\sum_{i=1}^n Stirling2(n,i)\bmod 999999598}\bmod 999999599\\&=&m^{B_n\bmod 999999598}\bmod 999999599\end{eqnarray*}\] 999999598=2*13*5281*7283,对于每个小质数依次计算,最后用中国剩余定理合并即可. 对于贝尔数,有 \[\begin{eqnarray*}B_{p+n}&\e

hdu 2521 一卡通大冒险 (斯特灵数,贝尔数)

/* 将N张卡分成若干个集合,集合不为空,有多少种分法. f[n][m]表示n张卡分成m组的种类数,那么f[n][m]=f[n-1][m-1]+f[n-1][m]*m,//第二类斯特灵数 而ans[n]=sum{f[n][l]}(1<=l<=m).//ans为贝尔数,Bell数是将P个元素集合分到非空且不可区分例子的划分个数. 其中:f[n-1][m-1]代表第n个人自成一堆: f[n-1][m]*m代表第n个人不自成一堆. */ # include <stdio.h> # inc

BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数(数位DP+恶心细节)

BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数 Time Limit: 5 Sec  Memory Limit: 64 MB Description 正如你所知,奶牛们没有手指以至于不能玩“石头剪刀布”来任意地决定例如谁先挤奶的顺序.她们甚至也不能通过仍硬币的方式. 所以她们通过"round number"竞赛的方式.第一头牛选取一个整数,小于20亿.第二头牛也这样选取一个整数.如果这两个数都是 "round numbers"

贝尔数(来自维基百科)&amp; Stirling数

贝尔数 贝尔数以埃里克·坦普尔·贝尔(Eric Temple Bell)为名,是组合数学中的一组整数数列,开首是(OEIS的A000110数列): Bell Number Bn是基数为n的集合的划分方法的数目.集合S的一个划分是定义为S的两两不相交的非空子集的族,它们的并是S.例如B3 = 5因为3个元素的集合{a, b, c}有5种不同的划分方法: {{a}, {b}, {c}} {{a}, {b, c}} {{b}, {a, c}} {{c}, {a, b}} {{a, b, c}}; B0

HDU2512 一卡通大冒险【斯特灵数,贝尔数】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2512 题目大意: 有N张卡,将N张卡分成若干不同的集合,集合不能为空.问:总共有多少种分法. 思路: 参考博文:http://blog.csdn.net/acm_cxlove/article/details/7857671 集合的个数可以为1.2.3.-.N.问题就变为了把N张卡放到i个集合中. 这时候个组合问题,可以用第二类斯特灵数解决. S(P,K) = S(P-1,K-1) + K*S(P-

HDU 2512 贝尔数

一卡通大冒险 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1356    Accepted Submission(s): 890 Problem Description 因为长期钻研算法, 无暇顾及个人问题,BUAA ACM/ICPC 训练小组的帅哥们大部分都是单身.某天,他们在机房商量一个绝妙的计划"一卡通大冒险".这个计

挑战程序设计竞赛 划分数,贝尔数,斯特灵数

斯特灵数:把n个数划分为恰好k个非空集合的个数,记为S(n,k).且有:S(n,1)=S(n,n)=1. 有递推关系式: S(n+1,k)=S(n,k?1)+kS(n,k?1) 贝儿数:把n个数划分为非空集合的所有划分数.有: Bn=∑i=0nS(n,i) 贝尔数的递推公式: Bn=∑k=0n(nk)Bk 书上的划分数:书上求的是:把n个相同的数划分为不超过m个集合的方法总数.由于这n个数是相同的,就不能算作∑ki=0S(n,i).书上给了这样一个dp的转移方程(定义dp[i][j]为j个数的i

hdu477 Bell——求第n项贝尔数

题意 设第 $n$ 个Bell数为 $B_n$,求 $B_n \ mod  \ 95041567$.($1 \leq  n  \leq  2^{31}$) 分析 贝尔数的概念和性质,维基百科上有,这里用到两点. 若 $p$ 是任意素数,有 $B_{p+n} = B_n + B_{n+1}(mod \ p)$ 每个贝尔数都是相应第二类斯特林数之和,即 $B_n = \sum_{k=1}^nS(n, k)$ 贝尔数的这个递推式只适合质数,我们可以将模数拆成质数,然后用CRT合并. $95041567

BZOJ 1485: [HNOI2009]有趣的数列( catalan数 )

打个表找一下规律可以发现...就是卡特兰数...卡特兰数可以用组合数计算.对于这道题,ans(n) = C(n, 2n) / (n+1) , 分解质因数去算就可以了... ---------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespa