题意
定义一个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)的可以先走了
- 首先思考一下关于函数性质,先假设 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....x−1且无法整除于 x x x,所以 i i i一定是 l c m ( 1 , 2 , 3.... x − 1 ) lcm(1,2,3....x-1) lcm(1,2,3....x−1)的倍数,所以显然易见,我们应该枚举答案,也就是这里的 x x x,判断这 n n n个数里面有几个 x x x以相乘的方式相加,时间复杂度将大大减少。
- 那么这
n
n
n个答案里面应该存在
n
/
l
c
m
(
1
,
2
,
3....
x
−
1
)
n/lcm(1,2,3....x-1)
n/lcm(1,2,3....x−1)个答案
x
x
x,但是不包括
l
c
m
(
1
,
2
,
3....
x
−
1
,
x
)
lcm(1,2,3....x-1,x)
lcm(1,2,3....x−1,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....x−1)包含于
l
c
m
(
1
,
2
,
3....
x
−
1
,
x
)
lcm(1,2,3....x-1,x)
lcm(1,2,3....x−1,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....x−1)−n/lcm(1,2,3....x−1,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);
}
}
有什么错误及时评论,蒻蒻萌新在线挨打