【题解】CF264B Good Sequences

【题解】CF264B Good Sequences

具有很明显的无后效性。

考虑\(dp\)

考虑初始条件,显然是\(dp(0)=0\)

考虑转移,显然是\(dp(t)=max(dp[k])+1\)其中\(gcd(data[t],data[k])>1\)

这样的转移是\(O(n^2)\)的!显然超时。

发现值域\(\le 100000\)那么我们将数拆成它的质因数。

线性筛素数预处理\([1,100000]\)的质数\(O(n)\)的代价。存下来。

然后转移的时候,先直接\(O(\sqrt{n})\)枚举质因数,直接从\(vector\)表里查询能够从谁那里转移。

根据\(dp\)的最优性质,可以知道只需要从\(vector\)的最后一个 \(dp\)值转移过来就好了,一定是最大的。

这样复杂度就是\(O(n\sqrt{n})\)

#include<bits/stdc++.h>

#define RP(t,a,b) for(register int (t)=(a),edd_=(b);t<=edd_;++t)
#define DRP(t,a,b) for(register int (t)=(a),edd_=(b);t>=edd_;--t)
#define ERP(t,a) for(int t=head[a];t;t=e[t].nx)
#define Min(a,b) ((a)<(b)?(a):(b))
#define pushup(x) seg[(x)]=seg[(x)<<1]+seg[(x)<<1|1]
#define midd register int mid=(l+r)>>1
#define chek if(R<l||r<L)return
#define TMP template<class ccf>
#define rgt L,R,mid,r,pos<<1|1
#define lef L,R,l,mid,pos<<1
#define all 1,n,1

using namespace std;typedef long long ll;
TMP inline ccf qr(ccf k){
    char c=getchar();
    ccf x=0;
    int q=1;
    while(c<48||c>57)q=c==45?-1:q,c=getchar();
    while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
    return q==-1?-x:x;
}
const int maxn=100005;
const int maxl=maxn-5;
bool usd[maxn];
int data[maxn];
#define isp(x) (!usd[x])
vector < int > pr;
#define pb push_back
vector < int > p[100001];
int n;
int ans;
int dp[maxn];

inline void gen_pr(){
    usd[1]=1;
    usd[0]=1;
    RP(t,2,maxl){
    if(!usd[t])
        pr.pb(t);
    RP(i,0,pr.size()-1){
        if(t*pr[i]>maxn)
        break;
        usd[t*pr[i]]=1;
        if(!(t%pr[i]))
        break;
    }
    }
}

inline int Max(int x,int y){
    if(x>y)
    return x;
    return y;
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("good.in","r",stdin);
    freopen("good.out","w",stdout);
#endif
    gen_pr();
    n=qr(1);
    RP(t,1,n)
    data[t]=qr(1);
    int siz=pr.size()-1;

    RP(t,1,n){register int sav=data[t];
    RP(i,0,siz){
        register int now=pr[i];
        register int nowcnt=p[now].size();
        if(!(sav%now)){
        while(!(sav%now))
            sav/=now;
        if(nowcnt)
            dp[t]=Max(dp[t],dp[p[now][nowcnt-1]]+1);
        else
            dp[t]=Max(dp[t],1);
        p[now].pb(t);
        }
        if(sav<now)
        break;
    }
    }
    
    ans=1;
    RP(t,1,n)
    ans=Max(ans,dp[t]);
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/winlere/p/10341825.html
今日推荐