| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
分享一个O(X log X)的类似dp的解法, 其中X是x的最大值类似于动态规划, 定义len[x]和num[x]两个数组, 分别表示1到x的最长路径长和最长路径数目. 枚举1到X中的每个整数(不只是素数)i, 对于i枚举i在X以内的所有倍数j, 在这个时候len[i]和num[i]都是已知的, 因此我们用这两个信息计算i对j的贡献, 如果len[i] + 1 > len[j], 则说明之前计算得到的到j的路径长应该被舍弃, 应当对len[j]进行更新, 并且将num[j]直接改为num[i], 如果len[i] + 1 == len[j], 说明发现了新的长度一样的路径, 那么把num[i]加到num[j]上. 完成预处理后对每个询问O(1)查询. 至于为什么预处理的复杂度是O(X log X), 因为预处理过程中循环的次数等于 X/1 + X/2 +X/3 ... +X/X, 提取各项的公因子X后剩下的是一个调和级数, 渐进上=O(log X), 因此总的复杂度是O(X log X).
code:
/*solution to POJ-3421:X-factor Chains*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX_X (1<<20)
int len[MAX_X + 1];
int num[MAX_X + 1];
vector<int> arr;
int main(void)
{
int x;
int mxx = 0;
while(cin >> x){
arr.push_back(x);
mxx = max(mxx, x);
}
len[1] = 0;
num[1] = 1;
for(int i = 1; i <= mxx; i++){
for(int j = 2*i; j <= mxx; j += i){
if(len[i] + 1 > len[j]){
len[j] = len[i] + 1;
num[j] = num[i];
}else if(len[i] + 1 == len[j]){
num[j] += num[i];
}
}
}
for(int i = 0; i < arr.size(); i++)
cout << len[arr[i]] << ' ' << num[arr[i]] << '\n';
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator