首页 > 其他分享 >P9488 ZHY 的生成树

P9488 ZHY 的生成树

时间:2023-09-08 10:48:18浏览次数:41  
标签:P9488 return ZHY ll 生成 fa int ans find

2023-07-31 19:29:29 solution

P9488 ZHY 的生成树

前言

这道题就非常的巧,下午上午上课刚讲完筛法,下午就考到了一个很像筛法的题。当时看到这个数据范围尽往线性做法想了,后面实在想不到就开始想如何带 \(\log\) 做,先拿个 \(60\)pts 再说。

思路

看到这样的求最大生成树,首先先排除真的两两连边跑 Prim,当然你可以通过这样拿到 \(30\)pts,但是我觉得码量太大不如想贪心做法。

一开始想到从大到小枚举每个数的每个因数和因数的倍数计算 \(\gcd\),但是考虑到这样不一定最优,得把所有情况都枚举出来并且还得排序,不如把 \(n\) 折半,然后从大到小枚举倍数,这样我们可以保证连的边最大并且值就是本身。

如果你直接这么打,显然会连第二个样例都过不了,会发现大了不少,这是为什么呢?因为题目让你求的是一棵树啊,每个点至少要连一条边,如果这样枚举会导致大质数不被连到。那如果你再加个数组判断每个数有没有被连到,还是会发现大了不少,因为树要保证点与点之间的联通性,你直接盲目连会导致最后出现的不是一棵树,而是一片森林。

在我把后面的暴力打完之后,我重新来思考这道题。联通性?那不如直接先把所有点连到 \(1\),然后再用上面的方法直接改变两条边的连接方式使其仍然联通,也就是判断两个点之间是否已经连过,然后断掉其中一个点连向 \(1\) 的边,建一个两点之间的边。如何判断是否连过?当然是并查集啊!判断两个点是否不经过 \(1\) 联通即可。

\(60\) pts \(Code\)

ll n,ans,fa[10000006];
inline ll find(ll x){
    if(x==fa[x])return x;
    return fa[x]=find(fa[x]);
}
int main(){
    cin>>n;ans=n-1;
    for(ll i=1;i<=n;i++)fa[i]=i;
    for(ll i=n/2;i>1;--i){
        for(ll j=i*2;j<=n;j+=i){
            if(find(i)!=find(j))fa[find(i)]=find(j),ans+=i-1;
        }
    }
    cout<<ans;
}

之后我一直以为瓶颈在并查集,因为我发现去掉并查集后跑的飞快。结果赛后参考了一下题解,发现每次乘的时候不应该一个一个乘,发现有很多次重复,发现如果加的是合数,那肯定前面已经有是你的倍数比你贡献大的连过了,那此时肯定会出现连过的情况。所以我们直接每次乘质数即可,与埃氏筛神似。

\(Code\)

int n,tot,fa[10000006],prime[10000004];
bool vis[10000004];
ll ans;
inline int find(int x){
    if(x==fa[x])return x;
    return fa[x]=find(fa[x]);
}
inline void init(){
    for(int i=2;i<=10000000;i++){
        if(!vis[i])prime[++tot]=i;
        for(int j=1;j<=tot&&i*prime[j]<=10000000;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)break;
        }
    }
}
int main(){
    cin>>n;  
    ans=n-1;
    init();
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=n/2;i>1;--i){
        for(int j=1;j<=tot&&i*prime[j]<=n;j++){
            if(find(i)!=find(prime[j]*i))fa[find(i)]=find(prime[j]*i),ans+=i-1;
        }
    }
    cout<<ans;
}

标签:P9488,return,ZHY,ll,生成,fa,int,ans,find
From: https://www.cnblogs.com/NBest/p/17686901.html

相关文章

  • .netcore 使用iTextSharp生成pdf文件
     使用Nuget添加iTextSharp引用主要代码usingiTextSharp.text.pdf;usingiTextSharp.text;usingSystem.IO;usingAutoMapper;usingSystem.Linq;usingSystem.Drawing;usingstaticiTextSharp.text.Font;usingSystem.Text;namespaceWebApi.Common.Service......
  • php-PhpSpreadsheet设置生成的excel文件列宽度及字体大小
    usePhpOffice\PhpSpreadsheet\Spreadsheet;usePhpOffice\PhpSpreadsheet\Writer\Xlsx;//创建新的Excel实例$spreadsheet=newSpreadsheet();//获取当前工作表$worksheet=$spreadsheet->getActiveSheet();//设置列宽自动调整的范围$worksheet->getStyle('B1:C1'......
  • Python 读取excel表1单元格 生成 表2 的超链接
    fromopenpyxlimportload_workbook#加载现有的工作簿fromopenpyxl.utilsimportget_column_letterwb=load_workbook("C:\\Users\\CMS01\\Desktop\\SCHH621TEG_LDO(PLDO、NLDO、CPLDO)测试需求_20230814.xlsx")#获取Sheet1和Sheet6sheet1=wb['Sheet7�......
  • Pycharm创建文件时,自动生成文件头注释(作者、日期等信息)
    Pycharm里【文件】-【设置】-【编辑器】-【文件和代码模板】-【PythonScript】里填写自己想要设置的模板内容,点击【确定】或【应用】。模板示例,可以根据自己的需求进行更改#coding:utf-8#Project:${PROJECT_NAME}#File:${NAME}.py#Author:李凤娟#Date:$DATE$TIME#I......
  • 视频上传过程中自动转换为flv格式并截图生成缩略图(Java调用命令实现)
    //视频上传过程中自动转换为flv格式并截图生成缩略图(Java调用命令实现)importjava.util.ArrayList;importjava.util.List;publicclassVideoProcess{System.out.println(oldfilepath+"->"+newfilename+"->"+newimg);List<String>commen......
  • 生成一个数据分析常用的python环境安装文件,使用conda安装
    当使用conda安装Python环境时,可以创建一个名为environment.yml的文件来指定要安装的软件包和其版本。以下是一个示例的environment.yml文件,其中包含了一些常用的数据分析软件包: name:data_analysischannels: -conda-forgedependencies: -python=3.8 -pand......
  • sqlserver自动生成32位字符串
    由于数据库中有一个表的主键类型为varchar(32),而在hibernate中的类型为uuid.hex。所以想通过sqlserver中直接通过写insertinto的sql语句来自动生成主键,可采用: selectREPLACE(CAST(CAST(NEWID()ASBINARY(10))+CAST(GETDATE()ASBINARY(6))ASUNIQUEIDENTIFIER),'-','')......
  • [转] Linux下的字典生成工具Crunch,创造自己的专属字典
    Crunch是一种创建密码字典工具,按照指定的规则生成密码字典,可以灵活的制定自己的字典文件。使用Crunch工具生成的密码可以输出到屏幕,保存到文件、或另一个程序。由其在渗透测试需要爆破的时候,字典的编排等直接影响到我们的爆破速度,对整个渗透测试流程起着十分重要的作用。0x00安......
  • Python 迭代、可迭代对象、迭代器、生成器总结
    迭代对list、tuple、str等类型的数据使用for...in...的循环语法从其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代可迭代对象不是所有对象都能使用for..in,比如数字10,把可以通过for...in...这类语句迭代读取一条数据供我们使用的对象称之为可迭代对象(Iterable......
  • vue 生成海报并下载
    用到插件   vue-canvas-poster 具体的使用方法:html:<vue-canvas-poster:widthPixels="0":painting="painting"@success="success"@fail="fail"></vue-canvas-poster><......