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); } };