0
点赞
收藏
分享

微信扫一扫

HDU4944 FSF’s game【因子和】【递推】

七公子706 2022-07-27 阅读 15


题目链接:

​​http://acm.hdu.edu.cn/showproblem.php?pid=4944​​


题目大意:

给你一个数N,求出A、B分别为 1*1、1*2、…、1*N、2*2、2*3、…、2*N、……、N*N 中 

A*B/gcd(A/K,B/K) 的值为多少。


解题思路:

设当 N = 1 时,ans[1] = 1*1/gcd(1,1) = 1。

N = 2 时,ans[2] = 1*1/gcd(1,1) + 1*2/gcd(1,2) + 2*2/gcd(2,2) + 2*2/gcd(1,1) = 9。

…… 

可看出:ans[N] = ans[N-1] + Σ N*i/gcd(N/K,i/K) (1<=i<=N),K 为 N 和 i 的公约数,也是

gcd(N,i)的约数。

Σ N*i/gcd(N/K,i/K) (1<=i<=N) ≡ N* Σ i * K/ (gcd(N,i) (1<=i<=N) ≡ N* Σ (i/c1 + i/c2 + …) 

(cj 为 gcd(N,i)的所有约数,也是 i 的所有因子) 。

那么我们可以枚举所有的 cj。cj 是 i 的因子,那么 i/cj 就是因子的系数。那么对于所有的 i (1<= i 

<= N)来说,我们可以计算出所有的可能数。对于cj,可得到系数为1、2、…、n/cj。

那么累加和就是 1+2+…+N/cj = (1 + N/cj)* (N/cj)/2。

则Σ N*i/gcd(N/K,i/K) (1<=i<=N) = N*(1 + N/cj)*(N/cj)/2。


AC代码:


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define LL __int64
using namespace std;


LL A[500050],Ans[500050];

int main()
{
for(LL i = 1; i <= 500000; ++i)
{
for(LL j = i; j <= 500000; j += i)
{
A[j] += (j/i+1)*(j/i)/2; //因子j
}
}




Ans[1] = 1;
for(LL i = 1; i <= 500000; ++i)
{
Ans[i] = Ans[i-1] + A[i]*i; //递推
Ans[i] %= (1LL << 32);
}

int T,N,kase = 0;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
printf("Case #%d: %I64d\n",++kase,Ans[N]);
}
return 0;
}



举报

相关推荐

0 条评论