CF1542C Strange Function

这篇博客介绍了CF1542C问题的解决方案,探讨了定义一个特殊函数f(i),该函数表示不为i的因子的最小正整数。博主首先分析奇数和偶数的情况,发现偶数的f(i)每隔特定周期会变化。通过建立因子表,确定了周期与f(i)的关系,提出利用最小公倍数计算每个f(i)的周期,并在遍历过程中按周期累加求和,最后给出了代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Before all

唉又没有时间打 CF,只好事后自己做了。。。

题目大意

定义一个函数 f(i)f(i)f(i) 表示不为 iii 的因子的最小正整数,比如 f(1)=2,f(2)=3,f(4)=3f(1)=2,f(2)=3,f(4)=3f(1)=2,f(2)=3,f(4)=3。现给出一个 n(n≤1016)n(n\le 10^{16})n(n1016),求 ∑i=1nf(i)\sum_{i=1}^{n}f(i)i=1nf(i) 的值 mod⁡109+7\operatorname{mod} 10^9+7mod109+7

Solution

从简单开始思考,显然,所有的奇数的 f(i)f(i)f(i) 都是 222。所以我们来考虑偶数。

偶数必然有因子 1,21,21,2,所以我们暂且认为偶数的 f(i)=3f(i)=3f(i)=3。为了接下来分析方便起见,我将偶数及其函数值打成一张表:

iii222444666888101010121212141414161616181818…\dots
f(i)f(i)f(i)333333444333333555333333444…\dots

不难看出,每 666 个会出现一个 444,每 121212 个会出现一个 555……

那么这个 666121212 是哪里来的呢?

我们不妨把 f(i)=3f(i)=3f(i)=3 的偶数表示为 222,除此以外的因子都比 333 大的形式。那么 666 就是 2×32\times 32×3,除此以外因子都比 444 大……

所以,我们可以先打表来算这个每一个 f(i)f(i)f(i) 的出现周期。我们需要保证这个值是包含因子 1,2,…,[f(i)−1]1, 2, \dots, [f(i)-1]1,2,,[f(i)1] 的最小值,设 f(i)−1f(i)-1f(i)1 的周期为 sss,那么这个值只需要在 sss 的基础上使得它能够被 f(i)−1f(i)-1f(i)1 整除,所以就是 f(i)−1f(i)-1f(i)1sss 的最小公倍数。

最后统计答案的时候,遍历每个 f(i)f(i)f(i) 的周期,由于我们是逐一考虑 f(i)f(i)f(i) 的,所以每次只要加上 ⌊ns⌋\left\lfloor\dfrac{n}{s}\right\rfloorsn 即可。

Code

#include<bits/stdc++.h>
#define ll long long
#define inf (1<<30)
#define INF (1ll<<60)
using namespace std;
const ll MAXN=1e16;
const ll MOD=1e9+7;
ll top[110];
void solve(){
	ll n;
	scanf("%lld",&n);
	ll ans=n*2%MOD;//加上奇数的值,并先把偶数的 3 加上 2
	ans=(ans+n/2)%MOD;//先钦定所有偶数都是 3,由于上一行中已经加了 2,所以这里每个偶数只要 +1
	for(int i=4;top[i]<=n;i++){
		ans=(ans+n/top[i])%MOD;
		//同理,我已经加了小 1 的值,所以这里每次只需要增加 1 就行
	}
	printf("%lld\n",ans);
}
ll gcd(ll x,ll y){return x%y==0?y:gcd(y,x%y);}
int main()
{
	for(ll i=4,cur=2;cur<=MAXN;i++){
		ll g=gcd(i-1,cur);
		cur=cur*(i-1)/g;
		top[i]=cur;
	}//打表,top[i] 表示 f(x)=i 的周期
	int T;
	for(scanf("%d",&T);T--;)
		solve();
	return 0;
}
/*

*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值