Description
玩具有很多不同的种类,每种玩具有很多歌,相同种类的两个玩具是无法区分的。
我们现在想知道总共有几个玩具。我们已知,如果在所有玩具中选择一些不同的玩具,可以玩 (n) 天,即任意两天选择的玩具中都存在任意一种玩具的数量不同,注意选择空集也是允许的。
输入仅包含一个正整数 (n)。
Solution
如果各种物品的数量分别为 (c_1,c_2,...,c_k),那么可以选择的方案数显然是在每种物品中选择一个个数,即 ((c_1+1)(c_2+1)...(c_k+1))。现在问题是反过来的,给定了方案数,因此我们考虑对这个数字作分解即可。
考虑对于 (n) 的所有的拆分,假设有一种拆分为 (a_1 cdot a_2 cdot ... cdot a_k),那么很显然 (a_1-1,a_2-1,...,a_k-1) 可以是答案之一,我们计算出这种方案的数目,然后扔进 set
里,最后统计一下即可。
比较有趣的是这个过程的复杂度……
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
int n;
set <int> st;
void solve(int n,int last,int sum)
{
for(int i=sqrt(n);i>=last;--i)
{
if(n%i==0)
{
solve(n/i,i,sum+i-1);
}
}
st.insert(sum+n-1);
}
signed main()
{
cin>>n;
solve(n,2,0);
cout<<st.size()<<endl;
for(int i:st)
{
cout<<i<<" ";
}
}