首页 > 其他分享 >【NC17450】因数个数和

【NC17450】因数个数和

时间:2024-03-25 15:31:01浏览次数:23  
标签:lfloor 10 个数 rfloor times 因数 sqrt NC17450

题目

因数个数和

因数个数,找规律

思路

根据题意,可以知道不可能使用朴素的方法挨个求解结果

对任意一个正整数 x x x,其所有因数的分布规律是要么小于等于 ⌊ x ⌋ \lfloor \sqrt x \rfloor ⌊x ​⌋,要么大于 ⌊ x ⌋ \lfloor \sqrt x \rfloor ⌊x ​⌋

于是可以枚举小于等于 ⌊ x ⌋ \lfloor \sqrt x \rfloor ⌊x ​⌋的因数,并在枚举过程中计算所有因数的个数之和。

对于小于等于 ⌊ x ⌋ \lfloor \sqrt x \rfloor ⌊x ​⌋的因数 i i i,可以直接求其贡献值,即 1 → x 1\to x 1→x 中有多少个数字含有该因子 i i i,可以求得 i i i 的贡献值为 ⌊ x i ⌋ \lfloor {x\over{i}} \rfloor ⌊ix​⌋,然后利用 i i i 求大于 ⌊ x ⌋ \lfloor \sqrt x \rfloor ⌊x ​⌋ 范围内的贡献,即找 i × m i\times m i×m,其中 m m m 是刚刚好大于 ⌊ x ⌋ \lfloor \sqrt x \rfloor ⌊x ​⌋ 并且 i × m i\times m i×m 还在 x x x 范围内的数字的个数,那么该数的范围为 ⌊ x ⌋ + 1 → ⌊ x i ⌋ \lfloor\sqrt x\rfloor+1 \to \lfloor {x\over{i}} \rfloor ⌊x ​⌋+1→⌊ix​⌋,贡献值则为 ⌊ x i ⌋ − ⌊ x ⌋ \lfloor {x\over{i}} \rfloor-\lfloor\sqrt x\rfloor ⌊ix​⌋−⌊x ​⌋

举个例子,比如求 1 → 10 1\to 10 1→10 的因数个数和,则有下面的过程:

  1. 首先是看 1 1 1 的贡献,为 10 / 1 10/1 10/1,共有 10 10 10 个数有 1 1 1 这个因子
  2. 然后是找 1 × m 1\times m 1×m,满足要求的数字有 1 × 4 , 1 × 5 , … 1 × 10 1\times 4,1\times 5,\dots 1\times 10 1×4,1×5,…1×10,共 7 7 7 个
  3. 看 2 2 2 的贡献,为 10 / 2 10/2 10/2,共有 5 5 5 个数有 2 2 2 这个因子
  4. 然后有 2 × 4 , 2 × 5 2\times 4,2\times 5 2×4,2×5,共 2 2 2 个
  5. 然后看 3 3 3 的贡献,为 10 / 3 10/3 10/3,共有 3 3 3 个数有 3 3 3 这个因子
  6. 然后由于 3 × 4 > 10 3\times 4>10 3×4>10,所以共 0 0 0 个
  7. 综上,总的因数个数和为 10 + 7 + 5 + 2 + 3 + 0 = 27 10+7+5+2+3+0=27 10+7+5+2+3+0=27

代码

#include <math.h>
#include <stdio.h>
typedef long long LL;

/**
 * @brief 计算 1 到 n 的因子个数和
 *
 * @param n
 * @return LL
 */
LL fact_cnt(int n) {
    LL res = 0;
    int s = sqrt(n);
    for (int i = 1; i * i <= n; i++) {
        // res += n / i;
        // res += n / i - s;
        // 下面这句是上面两句的合并
        res += (n / i << 1) - s;
    }
    return res;
}

int main(void) {
    int q = 0, n = 0;
    scanf("%d", &q);
    while (q--) {
        scanf("%d", &n);
        printf("%lld\n", fact_cnt(n));
    }
    return 0;
}

标签:lfloor,10,个数,rfloor,times,因数,sqrt,NC17450
From: https://blog.csdn.net/m0_52319522/article/details/137014661

相关文章

  • 分解质因数
    这段代码是一个简单的C++程序,用于将输入的整数分解为质因数并输出其质因数分解形式。程序的主要流程如下:引入 <bits/stdc++.h> 头文件:这个头文件实际上包含了C++标准库中的几乎所有头文件,因此它可以简化代码,但通常不建议在生产环境中使用,因为它可能导致编译时间增加。......
  • P1075 [NOIP2012 普及组] 质因数分解
    P1075[NOIP2012普及组]质因数分解[NOIP2012普及组]质因数分解题目描述已知正整数\(n\)是两个不同的质数的乘积,试求出两者中较大的那个质数。输入格式输入一个正整数\(n\)。输出格式输出一个正整数\(p\),即较大的那个质数。样例#1样例输入#121样例输出#1......
  • 添加区间到集合中,并计算出现在至少一个区间中的整数个数
    Leetcode题目:不断地添加区间到区间集合中,并计算出现在至少一个区间中的整数个数。使用BTreemap动态开区间。usestd::collections::BTreeMap;structCountIntervals{mp:BTreeMap<i32,i32>,cnt:i32,}implCountIntervals{fnnew()->Self{C......
  • 2605. 从两个数字数组里生成最小数字c
    intminNumber(int*nums1,intnums1Size,int*nums2,intnums2Size){intmin=INT_MAX;for(inti=0;i<nums1Size;i++){intsum=0;for(intj=0;j<nums2Size;j++){if(nums1[i]!=nums2[j]){if(nums1[i]>......
  • 每天一个数据分析题(二百二十五)
    ENN(EditedNearestNeighbors)方法是一种有效的处理类别不平衡问题时的方法,以下关于ENN算法的哪个描述是正确的?A.ENN主要移除多数类的样本B.ENN通过查找样本的最近邻居来判断是否移除它们C.ENN总是优先移除那些距离决策边界很远的样本D.ENN仅用于过采样题目来源于CD......
  • 每天一个数据分析题(二百二十六)
    当您使用网格搜索(GridSearch)进行超参数调优的时候,如果您有3个超参数,每个超参数有4个可能的值,进行5折交叉验证,那么您将训练多少次模型?A.60B.240C.320D.405题目来源于CDA模拟题库点击此处获取答案......
  • 判断一个数是否为质数
    首先我们要知道质数的定义:一个数只有1和它本身的数称为质数。接下来利用这一性质来写判断质数的代码。packagecom.ty.java;importjava.util.Scanner;publicclassDay2{publicstaticvoidmain(String[]args){Scannery=newScanner(System.in)......
  • lc3072 将元素分配到两个数组中2
    给定数组nums[n],定义f(arr,val)表示数组arr中大于val的元素个数,需要操作n次将nums分配到两个数组里,具体如下:第1次操作将nums[1]追加到arr1,第2次操作将nums[2]追加到arr2后续第i次操作:如果f(arr1,nums[i])>f(arr2,nums[i]),则将nums[i]追加到arr1。如果f(arr1,nums[i])<f(a......
  • MegaCli64查看磁盘损坏,错误个数统计情况
     如下,两个命令,是磁盘濒临崩坏,比如存在扇区损坏之类的事情发生。咨询的浪潮热线,报sn。他们的临界值是500,我们监控脚本是200告警。PredictiveFailureCount这个的数字比MediaErrorCount这个严重, #/opt/MegaRAID/MegaCli/MegaCli64-PDList-aALL-NoLog|grep-ierrorMe......
  • C语言经典例题 --- 公因数、素数、闰年
    文章目录如何用代码实现求两个值之间的最大公因数呢?如何计算闰年?如何用代码实现判断一个数是否为素数如何用代码实现求两个值之间的最大公因数呢?代码如下:#include<stdio.h>intmain(){intm=0;intn=0;intmin=0;scanf("%d%d",&......