zoukankan      html  css  js  c++  java
  • 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) P-Fear Factoring 区间内数的所有因数的和(除法分块)

    题意就是标题。

    思路:

    对于每个数 a 算出 1~a 的所有因数和sum(a),输出sum(b)-sum(a-1)。

    关键在于如何求出 sum。

    首先发现因数∈ 1 ≤ i ≤ n ,每个因数在区间[1,n]内的出现次数(不考虑4=2*2这样因数重复出现,这种情况2只算出现一次)等于 n/i (向下取整)。

    然后用 t = n/(n/i) 可以找到与因数i出现次数相同的最大因数(这里可能有点难理解,例如1~100区间内21作为因数出现的数字有 21 ,42 ,63 ,84;即四次。按计算机整数相除默认向下取整规则可以知道 t = 25,手算一下就出来了,25作为因子在区间内出现的数字有 25 ,50 ,75 ,100;也是四次,而且21~25 内的数组作为因子时在区间内出现的次数都为4次)

    所以得到求和公式 sum += (t+i)(t+1-i)/2*(n/i);

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 using namespace std;
     5 typedef unsigned long long LL;
     6 LL a,b;
     7 LL func(LL n){
     8     if ( n == 0) return 0;
     9     LL sum = 0;
    10     LL t = 0;
    11     for (LL i=1; i<=n; i=t+1) {//已经计算了出现次数相同的因子i~t,故i=t+1,这样也能满足不超时
    12          t = n/(n/i);
    13          //printf("#%lld %lld
    ",i,t);
    14          sum += (i+t)*(t+1-i)/2*(n/i);
    15          //printf("&%lld
    ",n/i);
    16     }
    17     return sum;
    18 }
    19 int main(){
    20     while (scanf("%lld%lld",&a,&b)==2) {
    21         printf("%lld
    ",func (b)-func(a-1));
    22     }
    23     return 0;
    24 }
    View Code
  • 相关阅读:
    筛选法求素数
    C/C++经典面试题目
    操作系统笔试面试基本内容
    Win32/MFC的基本概念
    STL采用的标准模板库
    数据结构基本概念
    SQL基础语句
    C/C++基础概念
    计算机网络基础概念
    流水作业 批作业调度
  • 原文地址:https://www.cnblogs.com/llllrj/p/9490087.html
Copyright © 2011-2022 走看看