DP+数学 恶心死我了 DP那部分没什么 数学的那部分各种细节各种繁琐呀
在比赛中就可以做出来这种题的人果然不一般 自己还需锻炼呀
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<set> #include<map> #include<string> #include<queue> #include<stack> #include <iomanip> using namespace std; #define LL long long const double eps=1e-6; const int INF=0x3f3f3f3f; const int N=52; const int M=1501; const long long MOD=1000000007; long long sum[N][N][M]; long long b[N]; bool prime( int n) { for ( int i=2;i*i<=n;++i) if (n%i==0) return false ; return true ; } long long C( long long n, int m) { int a[N],I=0; for ( int i=2;i<=m;++i) if (prime(i)) a[I++]=i; for ( int i=1;i<=m;++i) b[i]=n-m+i; for ( int i=2;i<=m;++i) { int k=i; for ( int j=0;j<I&&k>1;++j) if (k%a[j]==0) { k=k/a[j]; for ( int l=1;l<=m;++l) if (b[l]%(( long long )(a[j]))==0) {b[l]=b[l]/(( long long )(a[j])); break ;} --j; } } long long tmp=( long long )(1); for ( int i=1;i<=m;++i) tmp=(tmp*(b[i]%MOD))%MOD; return tmp; } class DistinctRemainders { public : int howMany( long long n, int m) { memset (sum,0, sizeof (sum)); for ( int i=0;i<=m;++i) sum[i][0][0]=( long long )(1); int a=0; for ( int i=1;i<=m;++i) { for ( int j=1;j<=i;++j) { for ( int l=0;l<=a;++l) { sum[i][j][l]=sum[i-1][j][l]; if (l-(i-1)>=0) sum[i][j][l]=(sum[i][j][l]+sum[i-1][j-1][l-(i-1)])%MOD; } } a=a+i; } long long ans=0; long long lm=( long long )(m); for ( int j=1;j<=m;++j) for ( int l=( int )(n%lm);l<M&&(( long long )(l)<=n);l+=m) { if (sum[m][j][l]>0) { long long h=(n-( long long )(l))/lm; if (h<0) continue ; long long tmp=C(h+j-1,j-1); for ( int w=1;w<=j;++w) tmp=(tmp*( long long )(w))%MOD; tmp=(tmp*sum[m][j][l])%MOD; ans=(ans+tmp)%MOD; } } return ( int )(ans); } }; |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步