[题解]luogu_P4161_(排列/lcm

首先是由一些环组成的,循环次数为环大小的lcm,现在求把n分成若干份lcm的个数,首先和只要小于等于n即可,不足的可以用1补全,

lcm是由每个质因数最高次幂组合而成的,所以每个数都设为质数的次幂最优,然后就变成了了背包,直接背包即可

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1009;
int n;
int prime[maxn],isprime[maxn],tot;
void pre(){
    isprime[1]=1;
    for(int i=2;i<=1000;i++){
        if(!isprime[i])prime[++tot]=i;
        for(int j=1;j<=tot;j++){
            if(i*prime[j]>n)break;
            isprime[i*prime[j]]=1;
            if(i%prime[j]==0)break;
        }
    }
}
inline ll qpow(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1)ans*=a;
        a*=a;
        b>>=1;
    }
    return ans;
}
ll f[maxn];
int main(){
    scanf("%d",&n);
    pre();
    f[0]=1; 
    for(int i=1;i<=tot;i++){
        for(int k=n;k>=1;k--)
        for(int j=1;qpow(prime[i],j)<=k;j++)
        f[k]+=f[k-qpow(prime[i],j)];
    }
    ll ans=0;
    for(int i=0;i<=n;i++)ans+=f[i];
    printf("%lld",ans);
}

 

posted @ 2019-10-30 14:45  羊肉汤泡煎饼  阅读(154)  评论(0编辑  收藏  举报