[题解]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); }