题目链接:1025:[SCOI2009]游戏
由置换群的知识显然序列会出现一些循环节
设第i个循环节的长度为len[i],那么答案就是lcm(len[i])
将len[i]分解质因数pi^ai后答案可以写为pi^(max(ai))的乘积
如果sigma(pi^ai)<=n存在解
所有设dp[i][j]为前i个质数组成和为j的方案数,然后就是很水的dp了
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=1010;
LL dp[maxn][maxn];
int p[maxn],N=0,n;
bool vis[maxn];
void pre_prime(){
for (int i=2;i<=maxn-5;++i){
if (!vis[i]) p[++N]=i;
for (int j=1;j<=N&&p[j]*i<=maxn-5;++j){
vis[p[j]*i]=1;
if (i%p[j]==0) break;
}
}
}
int main(){
pre_prime();
scanf("%d",&n);
dp[0][0]=1;
for (int i=1;i<=N;++i)
for (int j=0;j<=n;++j){
dp[i][j]=dp[i-1][j];
for (int k=p[i];k<=j;k*=p[i])
dp[i][j]+=dp[i-1][j-k];
}
LL ans=0;
for (int i=0;i<=n;++i) ans+=dp[N][i];
printf("%lld",ans);
}