bzoj3462: DZY Loves Math II

状态很差脑子不清醒了,柿子一直在推错。。。。

。。。

不难发现这个题实际上是一个完全背包

问题在于n太大了,相应的有质数的数量不会超过7个

假设要求sigema(1~plen)i pi*ci=n 的方案数

令xi=ci/(S*pi),yi=ci%(S/pi),注意yi<S/pi

则等价于sigema(1~plen)i S*xi+yi*pi=n

若令sigema(1~plen)i xi=m,则sigema(1~plen)yi*pi=n-m*S

n-m*S=sigema(1~plen)yi*pi<plen*S,可推出n/S-plen<m<=n/S

此时plen有用了,我们可以枚举m,那么对于x的方案用插板法得C(m+plen-1,plen-1),对于y直接背包plen*S,朴素的做法是O(plen*(plen*S)*S/pi)的,随便优化下就可以把S/pi去掉了,不过要稍微注意yi的限制。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int _=1e2;
const int maxn=7*2*1e6+_;
const LL mod=1e9+7;

int plen,p[10];
bool divi(int n)
{
    plen=0;
    for(int i=2;i*i<=n;i++)
        if(n%i==0)
        {
            p[0]+=i;p[++plen]=i;n/=i;
            if(n%i==0)return false;
        }
    if(n!=1)p[0]+=n,p[++plen]=n;
    return true;
}

LL inv[10];
void yu(){inv[1]=1;for(int i=2;i<=plen;i++)inv[i]=inv[mod%i]*(mod-mod/i)%mod;}
LL C(LL n,LL m)
{
    LL ret=1;
    for(int i=1;i<=m;i++)
    {
        ret=ret*(n%mod)%mod*inv[i]%mod; n--;
    }
    return ret;
}
LL f[2][maxn]; int now;
void DP(int S)
{
    int li=S*plen;
    now=0,f[now][0]=1;
    for(int i=1;i<=plen;i++)
    {
        now^=1;
        for(int j=0;j<li;j++)
        {
            f[now][j]=0;
            if(j-p[i]>=0)f[now][j]=(f[now][j]+f[now][j-p[i]])%mod;
            f[now][j]=(f[now][j]+f[now^1][j])%mod;
            if(j>=S/p[i]*p[i])f[now][j]=(f[now][j]-f[now^1][j-S/p[i]*p[i]]+mod)%mod;
        }
    }
}

int main()
{
    freopen("3.in","r",stdin);
    freopen("a.out","w",stdout);
    int S,Q;
    scanf("%d%d",&S,&Q);
    if(!divi(S)){while(Q--)puts("0");return 0;}
    yu();DP(S);
    while(Q--)
    {
        LL n;
        scanf("%lld",&n);n-=p[0];
        if(n<0){puts("0");continue;}
        
        LL ans=0;
        for(LL m=max(0LL,n/S-plen+1);m<=n/S;m++)
        {
            ans=(ans+C(m+plen-1,plen-1)*f[now][n-m*S])%mod;
        }
        printf("%lld
",ans);
    }
    
    return 0;
}
原文地址:https://www.cnblogs.com/AKCqhzdy/p/10588412.html