zoukankan      html  css  js  c++  java
  • CF264B Good Sequences

    题目大意:给定一个序列a1,a2,……,an,求满足以下要求的最长子序列:1.该序列是严格上升的,即x[i] < x[i+1](1<=i<=k-1),2.任意两个相邻的元素是非互质的,即gcd(x[i],x[i+1])>1(1<=i<=k-1)。(1<=n,a[i]<=105)

    思路:我们先将序列排序,满足严格上升的条件,然后可以很容易的列出一个动态转移方程:if(gcd(f[i],f[j])>1) f[i]=max(f[i],f[j]+1);(1<=j<i),但这个复杂度是O(n^2)的,无法通过,那么我们考虑优化。我们仔细观察这个式子(大雾,发现每个数只和他因数的倍数有关,再仔细观察又发现,对于一个因数x,他的k倍一定比他的i倍(i<k)大,而且第二大的是这个数的(k-1)倍,那么我们只需要枚举每个数的因数,每个数只和他前一个因数的倍数有关,这样复杂度就变成O(n·log(n))的了;

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<vector>
    using namespace std;
    const int MaxN=200000;
    int n,a[MaxN],id[MaxN],tot[MaxN],f[MaxN],nmax,vis;
    vector<int>fir[MaxN];
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i) scanf("%d",&a[i]),f[i]=1,tot[a[i]]=1;
        sort(a+1,a+n+1);nmax=a[n];
        for(int i=1;i<=n;++i) id[a[i]]=i;
        for(int i=2;i<=nmax;++i){vis=0;
            for(int j=i;j<=nmax;j+=i){
                if(tot[j]==1){
                    if(vis!=0) fir[id[j]].push_back(vis);
                    vis=id[j];
                }
            }
        }
        for(int i=1;i<=n;++i){
            for(int j=0;j<fir[i].size();++j){
                f[i]=max(f[fir[i][j]]+1,f[i]);
            }
        }nmax=0;
        for(int i=1;i<=n;++i) nmax=max(nmax,f[i]);
        printf("%d
    ",nmax);
        return 0;
    }
  • 相关阅读:
    Module build failed: TypeError: this.getResolve is not a function 安装node-sass运行报错
    RMAN Catalog 和 Nocatalog 的区别
    oracle 闪回区故障
    mysql windows 安装 错误
    git rejected
    oracle 计算机改名后监听无法启动
    mysql GTID
    java程序员技术范围
    activiti
    spring mybatis mysql 事务不起作用
  • 原文地址:https://www.cnblogs.com/X-rice/p/11218910.html
Copyright © 2011-2022 走看看