POI2012 ODL-Distance

本文深入解析了POI2012竞赛题目ODL-Distance,阐述了一种利用线性筛求质因数个数的算法,通过枚举因子与倍数来优化计算过程,确保找到最优解。文章提供了详细的数学表达式和C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接P3532 [POI2012]ODL-Distance
  • \(f_{i,j}\)表示他给定的函数,\(g_i\)表示\(i\)的质因数个数
  • 那么\[f_{i,j}=g_{\frac {i*j}{gcd^2}}\]
  • 考虑线性筛\(g_i\)
  • 那么对于每一个数\(w_i\)考虑枚举他的因子作为\(gcd\)
  • 也就是枚举\(x\),对于\(x\),枚举所有\(x\)的倍数\(y\)
  • 所以我们预处理出\(h_x\)表示\(x\)和他的倍数中,\(f_x\)的最小值的编号。
  • 但是我们在计算\(i\)这个数的答案的时候,不能用\(i\)来更新本身。
  • 所以在设\(p_x\)表示\(x\)和他的倍数中,\(f_x\)的次小值的编号。

  • 所以在更新每个位置的答案的时候,我们枚举\(gcd\),然后再枚举\(gcd\)\(h_x\)\(p_x\)
  • 假设当前值是\(a\),如果\(h_x\)是本身,就用\(p_x\)\(a\)去更新答案,否则就用\(h_x\)去更新答案。
  • \(f_{i,j}=g_i+g_j-2*g_{gcd}\)
  • 这样虽然不能保证\(x\)\(a,b\)\(gcd\),但是这样一定不是最优的,\(a,b\)\(gcd\)一定会被枚举到并且成为最优解,所以答案一定会被更新成最优的。

#include<bits/stdc++.h>
#define R register int
#define ll long long 
using namespace std;
const int N=1000001;
const int inf=2e9;
int n,Mx,w[N],ans[N];
int tot,c[N],f[N],g[N],cnt[N],Mark[N],prm[N>>2];
int gi(){
    R x=0,k=1;char c=getchar();
    while((c<'0'||c>'9')&&c!='-')c=getchar();
    if(c=='-')k=-1,c=getchar();
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x*k;
}
void init(){
    for(R i=2;i<=Mx;++i){
        if(!Mark[i])prm[++tot]=i,c[i]=1;
        for(R j=1;j<=tot&&prm[j]*i<=Mx;++j){
            Mark[i*prm[j]]=1,c[i*prm[j]]=c[i]+1;
            if(i%prm[j]==0)break;
        }
    }
}
int main(){
    freopen("9.in","r",stdin);
    freopen("s.out","w",stdout);
    n=gi();
    for(R i=1;i<=n;++i)w[i]=gi(),Mx=max(Mx,w[i]);
    init(),c[0]=2e9;
    for(R i=1;i<=n;++i){
        for(R j=1;j*j<=w[i];++j){
            if(w[i]%j)continue;
            R k=w[i]/j;
            if(c[w[i]]<c[w[f[j]]])g[j]=f[j],f[j]=i;
            else if(c[w[i]]<c[w[g[j]]])g[j]=i;
            if(j==k)continue;
            if(c[w[i]]<c[w[f[k]]])g[k]=f[k],f[k]=i;
            else if(c[w[i]]<c[w[g[k]]])g[k]=i;
        }
    }
    for(R i=1;i<=n;++i){
        R ans=0,Mn=2e9;
        for(R j=1;j*j<=w[i];++j){
            if(w[i]%j)continue;
            R k=w[i]/j,x=0;
            if(f[j]==i)x=g[j];
            else x=f[j];
            if(Mn>c[w[i]]+c[w[x]]-2*c[j]||(Mn==c[w[i]]+c[w[x]]-2*c[j]&&ans>x))
                Mn=c[w[i]]+c[w[x]]-2*c[j],ans=x;
            if(j==k)continue;
            if(f[k]==i)x=g[k];
            else x=f[k];
            if(Mn>c[w[i]]+c[w[x]]-2*c[k]||(Mn==c[w[i]]+c[w[x]]-2*c[k]&&ans>x))
                Mn=c[w[i]]+c[w[x]]-2*c[k],ans=x;
        }
        printf("%d\n",ans);
    }
    return 0;
}

转载于:https://www.cnblogs.com/Tyher/p/9924682.html

内容概要:本文档是关于基于Tecnomatix的废旧智能手机拆解产线建模与虚拟调试的毕业设计任务书。研究内容主要包括:分析废旧智能手机拆解工艺流程;学习并使用Tecnomatix软件搭建拆解产线的三维模型,包括设备、输送装置等;进行虚拟调试以模拟各种故障情况,并对结果进行分析提出优化建议。研究周期为16周,涵盖了文献调研、拆解实验、软件学习、建模、调试和论文撰写等阶段。文中还提供了Python代码来模拟部分关键流程,如拆解顺序分析、产线布局设计、虚拟调试过程、故障模拟与分析等,并实现了结果的可视化展示。 适合人群:本任务书适用于机械工程、工业自动化及相关专业的本科毕业生,尤其是那些对智能制造、生产线优化及虚拟调试感兴趣的学生。 使用场景及目标:①帮助学生掌握Tecnomatix软件的应用技能;②通过实际项目锻炼学生的系统建模和虚拟调试能力;③培养学生解决复杂工程问题的能力,提高其对废旧电子产品回收再利用的认识和技术水平;④为后续的研究或工作打下坚实的基础,比如从事智能工厂规划、生产线设计与优化等工作。 其他说明:虽然文中提供了部分Python代码用于模拟关键流程,但完整的产线建模仍需借助Tecnomatix商业软件完成。此外,为了更好地理解和应用这些内容,建议学生具备一定的编程基础(如Python),并熟悉相关领域的基础知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值