BZOJ1025 [SCOI2009]游戏
首先很显然的是,对于多组置换他们的周期就是置换长度的lcm
且长度之和等于n
而这些置换长度可能是多个px^ax的乘积,由于都是正数且都大于1所以乘积肯定比加和大
性质:若p1^a1+p2^a2+...+pm^am<=n①,则ans=p1^a1*p2^a2*..*pm^am②是n的一个可行答案。
如果①式大于n的话那么长度之和显然也会大于n,所以当且仅当①式小于等于n时有解
而且我们通过质因数次幂的枚举可以保证不会枚举重复且枚举全部。
这就转化为在①式条件下求(a1,a2,a3...an)的种类。
1 #include<bits/stdc++.h> 2 using namespace std; 3 long long f[1005][1005],ans; 4 int v[1005],cnt,p[1005],n; 5 void pri() 6 { 7 for(int i=2;i<=1000;++i) 8 { 9 if(!v[i])p[++cnt]=i; 10 for(int j=1;j<=cnt&&i*p[j]<=1000;++j) 11 { 12 v[i*p[j]]=1;if(i%p[j]==0)break; 13 } 14 } 15 } 16 int main() 17 { 18 scanf("%d",&n); 19 pri();f[0][0]=1; 20 for(int i=1;i<=cnt;++i) 21 { 22 for(int j=0;j<=n;++j)f[i][j]=f[i-1][j]; 23 for(int j=p[i];j<=n;j*=p[i]) 24 { 25 for(int k=0;k+j<=n;++k) 26 f[i][j+k]+=f[i-1][k]; 27 } 28 } 29 for(int i=0;i<=n;++i)ans+=f[cnt][i]; 30 printf("%lld\n",ans); 31 return 0; 32 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。