Tutorial of Codeforces Round 729 (Div.2) C. Strange Function

C. Strange Function

题意

定义一个f(x)为最小的正整数使这个正整数不被x整除,给出一个正整数n,1<=n<=1e16,让求 ∑ i = 1 n f ( i ) \sum_{i=1} ^{n}{f(i)} i=1nf(i) 使得答案对1e9+7取模

看到取值范围,暴力枚举 f ( i ) f(i) f(i)的可以先走了

  1. 首先思考一下关于函数性质,先假设 f ( i ) = x f(i)=x f(i)=x,那么得出 i i i一定能整除于 1 , 2 , 3.... x − 1 {1,2,3....x-1} 1,2,3....x1且无法整除于 x x x,所以 i i i一定是 l c m ( 1 , 2 , 3.... x − 1 ) lcm(1,2,3....x-1) lcm(1,2,3....x1)的倍数,所以显然易见,我们应该枚举答案,也就是这里的 x x x,判断这 n n n个数里面有几个 x x x以相乘的方式相加,时间复杂度将大大减少。
  2. 那么这 n n n个答案里面应该存在 n / l c m ( 1 , 2 , 3.... x − 1 ) n/lcm(1,2,3....x-1) n/lcm(1,2,3....x1)个答案 x x x但是不包括 l c m ( 1 , 2 , 3.... x − 1 , x ) lcm(1,2,3....x-1,x) lcm(1,2,3....x1,x),因为一旦乘以 x x x f ( i ) = x f(i)=x f(i)=x不成立,而且这里 n / l c m ( 1 , 2 , 3.... x − 1 ) n/lcm(1,2,3....x-1) n/lcm(1,2,3....x1)包含于 l c m ( 1 , 2 , 3.... x − 1 , x ) lcm(1,2,3....x-1,x) lcm(1,2,3....x1,x),所以真正的答案 x x x出现的次数应该是 n / l c m ( 1 , 2 , 3.... x − 1 ) − n / l c m ( 1 , 2 , 3.... x − 1 , x ) n/lcm(1,2,3....x-1)-n/lcm(1,2,3....x-1,x) n/lcm(1,2,3....x1)n/lcm(1,2,3....x1,x)
    我认为大概到这里题目的思路已经清晰,自我反思下遇到取值范围较大类型题不应该盲目找规律,而是耐心思考函数性质,要知道很容易找出规律的题并不是好题。
    AC代码
#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int mod=1e9+7;
ll w[55];
int main(){
	w[1]=1;
	for(ll i=2;;i++){
		w[i]=w[i-1]*i/__gcd(w[i-1],i);
		if(w[i]>1e16+100)break;
//		printf("%lld ",w[i]);
	}
	int t;
	scanf("%d",&t);
	while(t--){
		ll n;
		scanf("%lld",&n);
		ll ans=0;
		for(int i=2;;i++){
			ll op1=n/w[i];
			ll op2=n/w[i-1];
			ans+=(op2-op1)*i;
			ans%=mod;
			if(op1==0)break;
		}
		printf("%lld\n",ans);
	}
}

有什么错误及时评论,蒻蒻萌新在线挨打

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值