NOWCODER 中位因数(筛法)

本文解析了牛客网上一道涉及数学和算法的题目,通过筛选法求解给定数值范围内所有数的因数中位数,进而计算g(x)的值。详细介绍了筛选法的巧妙之处,并附上AC代码实现。

链接:https://ac.nowcoder.com/acm/contest/6015/F
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

给出函数的定义如下:
f(x)是所有能够整除 x 的数(包含 1 和 x )中的中位数向下取整的大小,
g(x)= ∑ i = 1 x f ( i ) \sum_{i=1}^{x}f(i) i=1xf(i)

输入描述:

输入包含多组数据,第一行为一个数字 T ( 1 ≤ T ≤ 10 ) T(1≤T≤10) T(1T10) ,表示测试数据组数。
接下来是 T 组数据,每组数据为一行,包含一个整数 x ( 1 ≤ x ≤ 1000000 ) x(1≤x≤1000000) x(1x1000000)

输出描述:

每组数据输出包含一个整数,表示 g(x) 的值,结果要求对 1e9+7 取模。

示例1
输入

3
1
2
3

输出

1
2
4

说明

能够整除 1 的数字有 1 ,故 f(1)=1;
能够整除 2 的数字有 1,2 所以中位数为 [ 1 + 2 2 ] = 1 [\frac{1+2}{2} ] = 1 [21+2]=1 f ( 2 ) = 1 f(2) = 1 f(2)=1
能够整除 3 的数字有 1,3 所以中位数为 [ 1 + 3 2 ] = 2 [\frac{1+3}{2}]=2 [21+3]=2 f ( 3 ) = 2 f(3) = 2 f(3)=2
从而得出 g ( 1 ) = 1 , g ( 2 ) = 2 , g ( 3 ) = 4 g(1) = 1,g(2) = 2,g(3) = 4 g(1)=1,g(2)=2,g(3)=4

示例2
输入

1
1000000

输出

677045223

思路:

  主要是求因数的中位数,这个筛法很巧妙,大佬给我讲的时候我一脸懵逼。。。哎,做好笔记好好学习吧

AC代码

#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const ll maxn=1e6,mod=1e9+7;
ll f[1000010],g[1000010],t,n;
int main() {
	for(int i=1; i<=sqrt(maxn); i++) {
		for(int j=i; j<=maxn; j+=i) {
			if(f[j]*f[j] <j) f[j]=i; //这里求j的所有因数的中位数
		}
	}
	for(int i=1; i<=maxn; i++) {
		f[i]=(f[i]+i/f[i])/2; //偶数个因数的时候中位数是中间两个中位数之和除以2
		g[i]=(g[i-1]+f[i])%mod;
	}
	cin>>t;
	while(t--) {
		cin>>n;
		cout<<g[n]<<endl;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值