#729 div2 C题 简单数论 lcm +思维( 计算贡献

C. Strange Function
看数据范围 O ( n ) O(n) O(n) 的复杂度肯定是不行了
f ( x ) f(x) f(x) 表示从 1 1 1 开始,第一个不是 x x x 因子的数
考虑每个数对答案的贡献, 2 2 2 的贡献值就是这些数中不是 2 2 2 的倍数的数的个数乘 2 2 2
3 3 3 的贡献为这些数中既不是 2 2 2 的倍数又不是 3 3 3 的倍数的数乘 3 3 3
4 4 4 的贡献度就是不是 2 , 3 , 4 2,3,4 2,3,4 倍数的数乘 4 4 4
关键在于求贡献为 x x x 的数的个数,这个些数的特征是:是 1 , 2 , 3 , . . . , x − 1 1,2,3,..., x - 1 1,2,3,...,x1 这些数的倍数, 不是 1 , 2 , 3 , . . . . x 1,2, 3,....x 1,2,3,....x 这些数的倍数
在这里插入图片描述
l c m ( 1 , 2 , 3 , . . . , x ) lcm(1,2,3,...,x) lcm(1,2,3,...,x) 比起 l c m ( 1 , 2 , 3 , . . . , x − 1 ) lcm(1,2,3,...,x-1) lcm(1,2,3,...,x1) 就是多了一个约束条件, x x x 也是因子,用总的(一直到 x − 1 x-1 x1 的)减去 x x x 也是它因子的数,剩下的就是 x x x 不是因子的数。
L c m Lcm Lcm 倍增
求每个数贡献的个数的解释
感谢大佬的讲解
code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = (ll)1e9 + 7;

ll lcm(ll a, ll b)
{
	return a / __gcd(a, b) * b;
}
void work()
{
    ll n; scanf("%lld", &n);
    ll Lcm = 1;
    ll ans = 0, cnt;
    for(int i = 2; Lcm <= n; ++i)
    {
        cnt = (n / Lcm - n / lcm(Lcm, i)) % mod;// 总的-含有i为因子的,就是f(x)=i的个数
        ans = (ans + cnt * i % mod) % mod;
        Lcm = lcm(Lcm, i);
    }
    ans = (ans % mod + mod) % mod;
    printf("%lld\n", ans);
}

int main()
{
    int T; scanf("%d", &T);
    for(int i = 1; i <= T; ++i) work();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值