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);
}
};
浙公网安备 33010602011771号