SRM 572 DIV 2 1000

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

    }

};

  

你可能感兴趣的:(div)