• 「日常训练」COMMON 约数研究(HYSBZ-1968)


    题意与分析

    感谢https://www.cnblogs.com/Leohh/p/7512960.html的题解。这题话说原来不在我的训练范围,正好有个同学问我,我就拿来做做。数学果然不是我擅长的啊,这么简单我都不会。。。
    简单说下自己的理解。
    从原题出发容易得到的朴素算法容易超时,所以要想到转化问题。原题要求1~n的因数之和,反过来说,就是求1~n中有几个数分别是1、2、…、n的倍数。这个弯子转过来,题目就容易写了。直接变成O(n)算法。

    有趣的是,如果数据规模变为$10^{12}$,这道题该如何写呢?前面O(n)算法时,得到的式子是ni=1ni∑i=1n⌊ni⌋。容易发现,ni⌊ni⌋会对若干个连续的i相等。这个相等的i的区间是什么呢?考虑$n=ki+p$,p若想最接近0,k应当为ni⌊ni⌋,此时的imaximax即为nni⌊n⌊ni⌋⌋。那么,直接让下个i变为imax+1imax+1即可。这段区间对答案的贡献是$(i_{max}−i_{origin}+1)∗k$。可以证明,这样的算法的复杂度是不同的$floor(n/i)$的个数,也就是$sqrt(n)$。

    代码

     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <vector>
     5 #define MP make_pair
     6 #define PB push_back
     7 #define fi first
     8 #define se second
     9 #define ZERO(x) memset((x), 0, sizeof(x))
    10 #define ALL(x) (x).begin(),(x).end()
    11 #define rep(i, a, b) for (int i = (a); i <= (b); ++i)
    12 #define per(i, a, b) for (int i = (a); i >= (b); --i)
    13 #define QUICKIO                  
    14     ios::sync_with_stdio(false); 
    15     cin.tie(0);                  
    16     cout.tie(0);
    17 using namespace std;
    18 
    19 template<typename T>
    20 T
    21 read()
    22 {
    23     T tmp; cin>>tmp;
    24     return tmp;
    25 }
    26 int ans[1000005];
    27 int
    28 main()
    29 {
    30     ZERO(ans);
    31     int n, tot=0; cin>>n;
    32     rep(i, 1, n)
    33     {
    34         tot+=n/i;
    35     }
    36     cout<<tot<<endl;
    37     return 0;
    38 }
    点我看高清美少女
    如非注明,原创内容遵循GFDLv1.3发布;其中的代码遵循GPLv3发布。
  • 相关阅读:
    数据库范式
    将DBF,XLS,XML,MDB文件导入C#DataGrid的方法
    在类文件中引用Server对象
    在使用了母版页的页面里加载css和js文件
    IIS 7.5 URL重写参数
    hdu Can you solve this equation?
    hdu Dome of Circus
    hdu Bone Collector
    hdu Turn the corner
    hdu 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
  • 原文地址:https://www.cnblogs.com/samhx/p/HYSBZ-1968.html
Copyright © 2020-2023  润新知