• LiberOJ #124. 除数函数求和 【整除分块】


    一、题目

      #124. 除数函数求和

    二、分析

      比较好的一题,首先我们要对题目和样例进行分析,明白题目的意思。

      由于对于每一个$d$,它所能整除的数其实都是定的,且数量是$ lfloor frac{n}{d} floor $ 最终推导出这个公式 $$  ans =   sum_{d=1}^{n} lfloor frac{n}{d} floor d^{k}$$

      对于$n <= 10^{7}$其实复杂度是可以接受的。但是对于求$d^{k}$这个复杂度如果直接用快速幂预处理肯定会T。

      所以,这里用到了一个比较巧妙的方法,即联系线性求欧拉函数,因为幂次方是可以直接相乘的,所以把每个数相当于拆成了素数的$k$次方,这样我们原先求$n$次的快速幂,现在只需要求$sqrt{n}$次快速幂,即所有素数求一次。然后线性筛一遍就可以了。

    三、AC代码

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 #define ll long long
     5 const int mod = 1e9 + 7;
     6 const int maxn = 1e7 + 13;
     7 int Sum[maxn], Prime[maxn], tot;
     8 bool isPrime[maxn];
     9 int n, k;
    10 
    11 int Pow(int a, int b)
    12 {
    13     int ans = 1;
    14     while(b)
    15     {
    16         if(b & 1)
    17         {
    18             ans = 1ll * ans * a % mod;
    19         }
    20         b >>= 1;
    21         a = 1ll * a * a % mod;
    22     }
    23     return ans;
    24 }
    25 
    26 void init()
    27 {
    28     tot = 0;
    29     memset(isPrime, 0, sizeof(isPrime));
    30     isPrime[0] = isPrime[1] = 1;
    31     Sum[1] = 1;
    32     for(int i = 2; i < maxn; i++)
    33     {
    34         if(!isPrime[i])
    35         {
    36             Prime[tot++] = i;
    37             Sum[i] = Pow(i, k);
    38         }
    39         for(int j = 0; j < tot && 1ll * Prime[j] * i < maxn; j++)
    40         {
    41             isPrime[i * Prime[j]] = 1;
    42             Sum[i * Prime[j]] = 1ll * Sum[i] * Sum[Prime[j]] % mod;
    43             if(i % Prime[j])
    44                 break;
    45         }
    46     }
    47 }
    48 
    49 int main()
    50 {
    51     int ans = 0;
    52     cin >> n >> k;
    53     init();
    54     for(int i = 1; i <= n; i++)
    55     {
    56         int t = n / i;
    57         ans = (ans + 1ll * t * Sum[i] % mod) % mod; 
    58     }
    59     cout << ans << endl;
    60     return 0;
    61 }
  • 相关阅读:
    C++11 新特性之 变长參数模板
    Cocos2dx 3.6源代码编译错误:syntax error : missing &#39;)&#39; before &#39;{&#39;
    android开发中,在java中怎样使用c提供过来char*
    cocos2d-x 3.1.1 学习笔记[11] http请求 + json解析
    T420s成功加装固态硬盘(SSD)
    我对GFWed的一些自己的见解
    css样式布局中position的那些事儿
    Tokyo Tyrant(TTServer)系列(一)-介绍和安装
    Linux 文件描述符和重定向
    装饰模式
  • 原文地址:https://www.cnblogs.com/dybala21/p/11245336.html
Copyright © 2020-2023  润新知