码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 2655: calc

时间:2018-07-06 01:41:59      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:solution   des   mat   整数   bit   输出   stdin   exit   names   

Description

一个序列a1,...,an是合法的,当且仅当:
长度为给定的n。
a1,...,an都是[1,A]中的整数。
a1,...,an互不相等。
一个序列的值定义为它里面所有数的乘积,即a1a2...an。
求所有不同合法序列的值的和。
两个序列不同当且仅当他们任意一位不一样。
输出答案对一个数mod取余的结果。

Solution

由于 \(f(A)\) 是一个关于 \(A\)\(n\) 次多项式 .
知道 \(f[1]...f[2*n+1]\) 然后插值一下就行了.
\(f[1]...f[2*n+1]\) 可以 \(DP\) 求出 , 强制序列递增 , 最后乘以 \(n!\) 就行了.

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int A,n,m,mod,f[N][N],inv[N],Fac[N];
int main(){
  freopen("pp.in","r",stdin);
  freopen("pp.out","w",stdout);
  cin>>A>>n>>mod;
  m=2*n+1;
  for(int i=1;i<=m;i++)f[1][i]=i;
  for(int i=2;i<=n;i++){
      int sum=0;
      for(int j=i-1;j<=m;j++){
          f[i][j]=1ll*j*sum%mod;
          sum=(sum+f[i-1][j])%mod;
      }
  }
  inv[0]=inv[1]=Fac[0]=1;
  for(int i=2;i<=m;i++)inv[i]=(mod-1ll*(mod/i)*inv[mod%i]%mod)%mod;
  for(int i=1;i<=m;i++)Fac[i]=1ll*Fac[i-1]*i%mod;
  for(int i=n;i<=m;i++)f[n][i]=1ll*f[n][i]*Fac[n]%mod;
  for(int i=n;i<=m;i++)f[n][i]=(f[n][i]+f[n][i-1])%mod;
  if(A<=m)cout<<f[n][A],exit(0);
  int ans=0;
  for(int i=n;i<=m;i++){
      int t=1;
      for(int j=1;j<=m;j++)
          if(i!=j)t=1ll*t*(A-j)%mod*(i>=j?inv[i-j]:-inv[j-i])%mod;
      ans=(ans+1ll*f[n][i]*t)%mod;
  }
  cout<<(ans+mod)%mod;
  return 0;
}

bzoj 2655: calc

标签:solution   des   mat   整数   bit   输出   stdin   exit   names   

原文地址:https://www.cnblogs.com/Yuzao/p/9270884.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!