[9.28模拟] good
题意:给出一个单调递增的序列{ai},要你构造一个序列{xi},使得:
1、xi∈{ai}
2、{xi}单调递增
3、gcd(xi,xi+1)>1
求出最长的{xi}序列
题解:
dp
dp[i]表示选第i个数的最大长度
显然可以n2的实现
考虑如何优化
利用gcd的性质,一个数只会被与它有公共质因子的数转移到,所以当一个数要被与它某一个质因子相同的数转移时,我们只需要考虑已知贡献最大的那个数即可
所以分解出每个数的质因子,利用每一个质因子作为代表进行转移即可
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
#define N 100010
using namespace std;
int n,cnt,ans,dp[N],pri[N],a[N],c[N];
bool mark[N];
vector<int> ve[N];
int gi() {
int x=0,o=1; char ch=getchar();
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') o=-1,ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return o*x;
}
void pre() {
for(int i=2; i<=100000; i++) {
if(!mark[i]) pri[++cnt]=i;
for(int j=1; j<=cnt && i*pri[j]<=100000; j++) {
mark[i*pri[j]]=1;
if(i%pri[j]==0) break;
}
}
for(int j=1; j<=cnt; j++)
for(int i=pri[j]; i<=100000; i+=pri[j])
ve[i].push_back(pri[j]);
}
int main() {
n=gi();
pre();
for(int i=1; i<=n; i++) a[i]=gi();
for(int i=1; i<=n; i++) {
int siz=ve[a[i]].size();
for(int j=0; j<siz; j++) dp[i]=max(dp[i],c[ve[a[i]][j]]+1);
for(int j=0; j<siz; j++) c[ve[a[i]][j]]=max(c[ve[a[i]][j]],dp[i]);
}
for(int i=1; i<=n; i++) ans=max(ans,dp[i]);
printf("%d", ans);
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥