[CodeForces] 264B Good Sequences

题意:求最长严格上升子序列,并保证该子序列相邻不互质(数据范围:元素个数10^5,元素大小10^5)

 

题目突破点每个数组元素大小不超过10^5,预先将所有数分解质因数O(N*|prime|),或者筛出所有数的因子O(N*lgN)。

dp[num[i]]=max(dp[num[i]的因子]+1) (dp[i]为以i为结尾的最长子序列长度)

 

后来瞻仰了CLJ神牛的代码,STL用的很神,就顺手剽窃过来了……

 

View Code
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cmath>
 6 #include <string>
 7 #include <vector>
 8 #include <list>
 9 #include <map>
10 #include <set>
11 #include <queue>
12 #include <stack>
13 #include <bitset>
14 #include <algorithm>
15 #include <numeric>
16 #include <functional>
17 using namespace std;
18 typedef long long ll;
19 #define inf (int)1e10
20 #define exp 1e-8
21 #define read freopen("in.txt","r",stdin)
22 #define write freopen("out.txt","w",stdout)
23 #define maxn 100005
24 vector<int>dx[maxn];
25 int dp[maxn];
26 void init()//筛因子O(N*lgN)
27 {
28     for(int i=2;i<maxn;i++)
29         for(int j=i;j<maxn;j+=i)
30             dx[j].push_back(i);
31 }
32 int main()
33 {
34     //read;
35     init();
36     int n,num;
37     while(~scanf("%d",&n))
38     {
39         memset(dp,0,sizeof(dp));
40         for(int i=0;i<n;i++)
41         {
42             scanf("%d",&num);
43             int t=1;
44             for(vector<int>::iterator e=dx[num].begin();e!=dx[num].end();e++)//求当前num的最大上升不互质数列长度
45                 t=max(t,dp[*e]+1);
46             for(vector<int>::iterator e=dx[num].begin();e!=dx[num].end();e++)//用t更新num的因子dp值
47                 dp[*e]=max(dp[*e],t);
48         }
49         int ans=1;
50         for(int i=0;i<maxn;i++)
51             ans=max(ans,dp[i]);
52         printf("%d\n",ans);
53     }
54     return 0;
55 }

 

posted @ 2013-01-22 20:06  McFlurry  阅读(411)  评论(0编辑  收藏  举报