【51nod1220】约数之和

题目

d(k)表示k的所有约数的和。d(6) = 1 + 2 + 3 + 6 = 12。
定义S(N) = ∑1<=i<=N ∑1<=j<=N d(i*j)。
例如:S(3) = d(1) + d(2) + d(3) + d(2) + d(4) + d(6) + d(3) + d(6) + d(9) = 59,S(1000) = 563576517282。
给出正整数N,求S(N),由于结果可能会很大,输出Mod 1000000007(10^9 + 7)的结果。

分析

分开处理每个质因子,于是\(d(i*j)=\sum_{p|i}\sum_{q|j}\dfrac{iq}{p}[gcd(p,q)=1]\)
\[ans=\sum_{i=1}^{n}\sum_{j=1}^{n}\sum_{p|i}\sum_{q|j}\dfrac{iq}{p}[gcd(p,q)=1]\]
上一波反演,
\[=\sum_{d=1}^{n}\mu(d)\sum_{i=1}^{n}\sum_{j=1}^{n}\sum_{p|i}\sum_{q|j}\dfrac{iq}{p}[d|gcd(p,q)]\]
\[=\sum_{d=1}^{n}\mu(d)\sum_{p|i}\sum_{q[j}\dfrac{q}{p}\sum_{p[i}i\sum_{q[j}\]
\[=\sum_{d=1}^{n}\mu(d)\sum_{p|i}\sum_{q[j}\dfrac{q}{p}{\lfloor\dfrac{n}{q}\rfloor}{p\dfrac{\lfloor\dfrac{n}{p}\rfloor(\lfloor\dfrac{n}{p}\rfloor+1)}{2}}\]
\[=\sum_{d=1}^{n}\mu(d)d(\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}q{\lfloor\dfrac{n}{dq}\rfloor})(\sum_{q=1}^{\lfloor\frac{n}{d}\rfloor}{\dfrac{\lfloor\dfrac{n}{dp}\rfloor(\lfloor\dfrac{n}{dp}\rfloor+1)}{2}})\]
考虑处理\(\sum_{q=1}^{\lfloor\frac{n}{d}\rfloor}{\dfrac{\lfloor\dfrac{n}{dp}\rfloor(\lfloor\dfrac{n}{dp}\rfloor+1)}{2}}\)
用\(n\)代替\(\lfloor\dfrac{n}{d}\rfloor\)

\[\sum_{i=1}^{n}{\dfrac{\lfloor\dfrac{n}{i}\rfloor(\lfloor\dfrac{n}{i}\rfloor+1)}{2}}\]
\[=\sum_{i=1}^{n}\sum_{j=1}^{\lfloor\dfrac{n}{i}\rfloor}j\]
\[=\sum_{j=1}^{n}j\sum_{i=1}^{\lfloor\dfrac{n}{j}\rfloor}\]
\[=\sum_{j=1}^{n}j\lfloor\dfrac{n}{j}\rfloor(事实上,这就等于\sum_{j=1}^{n}d(j))\]
\[ans=\sum_{d=1}^{n}\mu(d)d(\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}q{\lfloor\dfrac{n}{dq}\rfloor})^2\]
于是对于两层\(\sum\)都分块处理
类似与【51nod 2026】Gcd and Lcm,可以用杜教筛处理\(\mu(d)d\)的前缀和。
对于\(\sum_{j=1}^{n}j\lfloor\dfrac{n}{j}\rfloor\),直接上分块。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
const int maxlongint=2147483647;
const long long mo=1e9+7;
const int lim=1e5+7;
const int N=10000005;
using namespace std;
#define sqr(x) (1ll*(x)*(x)%mo)
#define val(x,y) (1ll*(y-x+1)*(x+y)/2%mo)
int p[N],mu[N],n,ha[lim+5][2],s[N],ans;
bool bz[N];
int get(int v)
{
    int x;
    for(x=v%lim;ha[x][0] && ha[x][0]!=v;(++x)-=x>=lim?lim:0);
    return x;
}
int S(int m)
{
    if(m<=N-5) return s[m];
    int pos=get(m);
    if(ha[pos][0]) return ha[pos][1];
    ha[pos][0]=m;
    int la=0,sum=0;
    for(int i=2;i<=m;i=la+1)
    {
        la=m/(m/i);
        sum=(1ll*sum+1ll*val(i,la)*S(m/i))%mo;
    }
    return ha[pos][1]=(1-sum+mo)%mo;
}
int main()
{
    scanf("%d",&n);
    mu[1]=s[1]=1;
    for(int i=2;i<=N-5;i++)
    {
        if(!bz[i]) mu[p[++p[0]]=i]=-1;
        s[i]=(s[i-1]+mu[i]*i+mo)%mo;
        for(int j=1,k;j<=p[0] && (k=i*p[j])<=N-5;j++)
        {
            bz[k]=true;
            if(i%p[j]==0) break;
            mu[k]=-mu[i];
        }
    }
    int la=1;
    for(int i=1;i<=n;i=la+1)
    {
        la=n/(n/i);
        int last=1,nn=n/i,sum=0;
        for(int j=1;j<=nn;j=last+1)
        {
            last=nn/(nn/j);
            sum=(1ll*sum+1ll*(val(j,last))*(nn/j))%mo;
        }
        ans=(1ll*ans+1ll*(S(la)-S(i-1)+mo)*sqr(sum))%mo;
    }
    printf("%d",ans);
}

原文地址:https://www.cnblogs.com/chen1352/p/9099480.html

时间: 2024-10-05 03:14:53

【51nod1220】约数之和的相关文章

数学:求一个数的真约数(因数)的个数及所有约数之和

一. 我们知道,每个自然数(不包括0和1)都有2个以上的因数,因数最少的是质数(也叫素数),质数的因数是1和它本身.非质数的自然数也叫合数,它们都含有3个以上(含3个)的因数. 1.怎样求一个数有多少个因数? 对于一个已知的自然数,要求出它有多少个因数,可用下列方法: 首先将这个已知数分解质因数,将此数化成几个质数幂的连乘形式,然后把这些质数的指数分别加一,再相乘,求出来的积就是我们要的结果. 例如:求360有多少个因数. 因为360分解质因数可表示为:360=2^3×3^2×5,2.3.5的指

(c语法百题20)约数之和

知识点: 求约数的算法 for语句,if语句灵活运用. 内容: 键入一个自然数 ,求这个自然数的所有约数之和 输入说明: 一个整数 输出说明: 一个整数 输入样例: 6 输出样例: 12 1 #include <stdio.h> 2 int main() 3 { 4 int n,s=0,i; 5 scanf("%d",&n); 6 for (i=1;i<=n;i++) 7 { 8 if (n%i==0) 9 { 10 s=s+i; 11 } 12 } 13 p

【动态规划】mr359-最大公约数之和

[题目大意] 选取和不超过S的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大. 输入一个正整数S. 输出最大的约数之和. 样例输入 Sample Input 11 样例输出 Sample Output 9 样例说明 取数字4和6,可以得到最大值(1+2)+(1+2+3)=9. 数据规模对于30%的数据,S≤10: 对于100%的数据,S≤1000. [思路] 水题,普通的01背包问题,唯一需要注意的一点是,1的所有约数之和是0!我一开始就因为1没有单独判断而导致了错误. 1 #inc

POJ1845Sumdiv题解--约数之和

题目链接 https://cn.vjudge.net/problem/POJ-1845 分析 \(POJ\)里的数学题总是这么妙啊 首先有一个结论就是\(A=\prod{ \ {p_i}^{c_i} \ }\),那么\(A\)所有约数之和为\((1+p_1+p_1^2+..+p_1^{c_1}) * (1+p_2+p_2^2+...+p_2^{c_2}) ... (1+p_n +p_n^2 +... + p_n^{c_n})\) 这个好像数学归纳法可证,但是感性理解一下也不难 于是这道题就是求\

51nod 1220 约数之和(杜教筛 + 推推推推推公式)

题意 给出\(n(1\leq n \leq 10^9)\),求\(\sum_{i=1}^n\sum_{j=1}^n\sigma(ij)\),其中\(\sigma(n)\)表示\(n\)的约数之和. balabala 交了两道杜教筛的的板子题(51nod 1239, 1244)就看到了这题,然后不会搞,然后看题解看了一天一夜终于彻底搞明白一发A掉了...感觉学到了很多,写个博客整理一下,如有错请指出. 技能需求 数论函数与线性筛 莫比乌斯反演(也可以当成容斥去理解) 狄利克雷卷积 杜教筛 强大的数

51nod 1220 约数之和

约数之和 Problem d(k)表示k的所有约数的和.d(6) = 1 + 2 + 3 + 6 = 12. 定义S(N) = ∑1<=i<=N ∑1<=j<=N d(i*j). 例如:S(3) = d(1) + d(2) + d(3) + d(2) + d(4) + d(6) + d(3) + d(6) + d(9) = 59,S(1000) = 563576517282. 给出正整数N,求S(N),由于结果可能会很大,输出Mod 1000000007(10^9 + 7)的结果.

19: 约数之和

19 约数之和 作者: 朱星垠 时间限制: 1S 章节: 循环 问题描述 : 输入一个正整数(小于1000),计算这个正整数所有约数的和,并打印输出. 输入说明 : 你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据.每组输入数据由一行组成,每行为一个正整数. 输出说明 : 对每组测试数据,你的程序需要向标准输出文件(通常为启动该程序的文本终端)依次输出一组对应的答案:这个正整数所有约数的和,所有数据前后没有多余的空行,两组数据之间也没有多余的空行. 输入范例 : 1 10 输出范例 :

AcWing - 97 - 约数之和(分治、因数和)

题目链接 ??我们首先要知道怎么来求A的约数之和.首先,把A分解质因数,可得:\(A = q1^{k1}\times q2^{k2} ... \times \ qn^{kn}\) 然后我们用乘法的分配律可得A的因数之和为\(F(A) = (q1^0 + q1^1 + ... + q1^{k1}) \times (q2^0 + q2^1 + ... + q2^{k2})\ ... \times \ (qn^0 + qn^1 + ... + qn^{kn})\) ??那么对于\(A^B\)来说,\(

HDU 1215 七夕节(约数之和)

七夕节 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 39837    Accepted Submission(s): 12523 Problem Description 七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!" 人们纷纷来到