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}&\equiv&B_n+B_{n+1}(\bmod p)\\
B_{p^m+n}&\equiv&mB_n+B_{n+1}(\bmod p)\end{eqnarray*}\]

根据这两个公式,可以从高位到低位递推,当$n<p$时直接输出解。时间复杂度$O(p^2\log p)$。

 

#include<cstdio>
typedef long long ll;
const int N=7284,P=999999598;
ll n,m;int a[4]={2,13,5281,7283},f[N],s[2][N],i,j,x;
int cal(int x,ll n){
  int i,j,k,m=0,b[N],c[N],d[70];
  for(i=0;i<=x;i++)b[i]=f[i]%x;
  while(n)d[m++]=n%x,n/=x;
  for(i=1;i<m;i++)for(j=1;j<=d[i];j++){
    for(k=0;k<x;k++)c[k]=(b[k]*i+b[k+1])%x;
    c[x]=(c[0]+c[1])%x;
    for(k=0;k<=x;k++)b[k]=c[k];
  }
  return c[d[0]];
}
ll pow(ll a,ll b,ll p){ll t=1;for(a%=p;b;b>>=1LL,a=a*a%p)if(b&1LL)t=t*a%p;return t;}
ll bell(ll n){
  if(n<N)return f[n];
  ll t=0;
  for(int i=0;i<4;i++)t=(t+(P/a[i])*pow(P/a[i],a[i]-2,a[i])%P*cal(a[i],n)%P)%P;
  return t;
}
int main(){
  f[0]=f[1]=s[0][0]=1,s[0][1]=2;
  for(i=2,x=1;i<N;i++,x^=1)for(f[i]=s[x][0]=s[x^1][i-1],j=1;j<=i;j++)s[x][j]=(s[x^1][j-1]+s[x][j-1])%P;
  scanf("%lld%lld",&n,&m);
  printf("%lld",pow(m,bell(n),P+1));
  return 0;
}

  

posted @ 2015-08-09 02:38  Claris  阅读(593)  评论(0编辑  收藏  举报