2010-1167
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
/*补题解工程..表示有点忘了算法了*/
题目大意:
求perfect square number set.
定义perfect square number set:
*必须是一个square number set
*元素的乘积是一个square number
定义square number set:
组成的元素是square number
定义square number:
不能被平方数整除
分析:
关键点是元素乘积也必须是square number
也就是说,对最后的乘积进行质因数分解,一个质因数的次数<=1
如果没有元素范围限制,则可以借用第二类斯特林数。由于这个限制,所以采用搜索办法。
贴一下看到的AC代码,由于里面用了STL的一些数据结构,理解不能。
#include<vector>
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
#include<sstream>
#include<set>
#include<map>
#define sqr(x) ((x)*(x))
using namespace std;
const int rest = 1000000007;
map<pair<int, pair<int, vector<int> > >, int> d;
vector<int> prim;
int n, k;
int dfs(int cur, int num, vector<int> a)
{
if (cur == prim.size()) return (num > 0);
while (a.size() > 0 && a[a.size() - 1] * prim[cur] > n) a.pop_back();
pair<int, pair<int, vector<int> > > tp = make_pair(cur, make_pair(num, a));
if (d.find(tp) != d.end()) return d[tp];
int val;
val = dfs(cur + 1, num, a);
vector<int> b;
if (num < k)
{
b = a; b.push_back(prim[cur]);
sort(b.begin(), b.end());
val = (val + dfs(cur + 1, num + 1, b)) % rest;
}
for (int i = 0; i < a.size(); i++)
{
b = a; b[i] = b[i] * prim[cur];
sort(b.begin(), b.end());
val = (val + dfs(cur + 1, num, b)) % rest;
}
d[tp] = val; return val;
}
class SquareFreeSets
{
public:
int countPerfect(int N, int K)
{
n = N; k = K;
for (int i = 2; i <= N; i++)
{
bool flag = true;
for (int j = 2; j * j <= i; j++)
if (i % j == 0)
{
flag = false; break;
}
if (flag) prim.push_back(i);
}
vector<int> st;
return dfs(0, 0, st);
}
};
int main()
{
// freopen("square.in", "r", stdin);
// freopen("square.out", "w", stdout);
int N, K;
while (cin >> N >> K) {
prim.clear();
vector<int>().swap(prim);
d.clear();
cout << SquareFreeSets().countPerfect(N, K) << endl;
}
return 0;
}
/*补题解工程..表示有点忘了算法了*/
题目大意:
求perfect square number set.
定义perfect square number set:
*必须是一个square number set
*元素的乘积是一个square number
定义square number set:
组成的元素是square number
定义square number:
不能被平方数整除
分析:
关键点是元素乘积也必须是square number
也就是说,对最后的乘积进行质因数分解,一个质因数的次数<=1
如果没有元素范围限制,则可以借用第二类斯特林数。由于这个限制,所以采用搜索办法。
贴一下看到的AC代码,由于里面用了STL的一些数据结构,理解不能。
#include
#include
#include
#include
#include
#include
#include
#include
#define sqr(x) ((x)*(x))
using namespace std;
const int rest = 1000000007;
map
vector
int n, k;
int dfs(int cur, int num, vector
{
if (cur == prim.size()) return (num > 0);
while (a.size() > 0 && a[a.size() - 1] * prim[cur] > n) a.pop_back();
pair
if (d.find(tp) != d.end()) return d[tp];
int val;
val = dfs(cur + 1, num, a);
vector
if (num < k)
{
b = a; b.push_back(prim[cur]);
sort(b.begin(), b.end());
val = (val + dfs(cur + 1, num + 1, b)) % rest;
}
for (int i = 0; i < a.size(); i++)
{
b = a; b[i] = b[i] * prim[cur];
sort(b.begin(), b.end());
val = (val + dfs(cur + 1, num, b)) % rest;
}
d[tp] = val; return val;
}
class SquareFreeSets
{
public:
int countPerfect(int N, int K)
{
n = N; k = K;
for (int i = 2; i <= N; i++)
{
bool flag = true;
for (int j = 2; j * j <= i; j++)
if (i % j == 0)
{
flag = false; break;
}
if (flag) prim.push_back(i);
}
vector
return dfs(0, 0, st);
}
};
int main()
{
// freopen("square.in", "r", stdin);
// freopen("square.out", "w", stdout);
int N, K;
while (cin >> N >> K) {
prim.clear();
vector
d.clear();
cout << SquareFreeSets().countPerfect(N, K) << endl;
}
return 0;
}