专栏文章

题解:CF822D My pretty girl Noora

CF822D题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mir2lgx8
此快照首次捕获于
2025/12/04 14:43
3 个月前
此快照最后确认于
2025/12/04 14:43
3 个月前
查看原文

CF822D My pretty girl Noora 题解

个人认为题意翻译已经足够清晰,于是我就不再赘述了。

思路

首先,看到筛选方法,感到很奇怪,于是我便觉得这是到找规律题,于是开始推式子。
假设按照 xx 人一组淘汰,那么:
  • 这一组淘汰 xx 个人;
  • 这一组有 x×(x1)2\frac{x\times (x-1)}{2} 次比较。
所以平均每 x×(x1)2x=x12\frac{\frac{x\times (x-1)}{2}}{x}=\frac{x-1}{2} 次比较淘汰一个人,显然,要使比较最少,x12\frac{x-1}{2} 也要尽可能小,所以 xx 要尽可能小。又因为 xmx\,|\,mmm 的含义与题目相同) ,所以 xx 应取 mm 的最小质因子。
所以我们有了递推方程,设 xx 的最小质因子为 g(x)g(x),则: f(i)=f(ig(i))+g(i)×(g(i)1)2×ig(i)f(i)=f(\frac{i}{g(i)})+\frac{g(i)\times(g(i)-1)}{2}\times\frac{i}{g(i)} 化简得: f(i)=f(ig(i))+i×(g(i)1)2f(i)=f(\frac{i}{g(i)})+\frac{i\times(g(i)-1)}{2}
我们注意到,2lr5×1062\le l\le r\le 5\times 10^6,所以我们可以做一遍质数筛,预处理出每个数的质因子,然后从 22nn 递推即可。

Code

CPP
#include <bits/stdc++.h>
using namespace std;

#define int long long
constexpr int maxn = 5000010, modd = 1e9 + 7;

int t, l, r, poww, ans;

int p[maxn], book[maxn], cnt;
int g[maxn]; //最小质因数
void prime() { // 质数筛
	for (int i = 2; i <= 5000000; i++) {
		if (!book[i]) {
			p[++cnt] = i;
			g[i] = i; //求最小质因数
		}
		for (int j = 1; j <= cnt && i * p[j] <= 5000000; j++) {
			book[i * p[j]] = 1;
			g[i * p[j]] = p[j]; //求最小质因数
			if (i % p[j] == 0) {
				break;
			}
		}
	}
	return ;
}

int M(int x) { //一个万能取模,非常好用,强烈推荐!!!
	return ((x < 0) ? ((x % modd + modd) % modd) : ((x < modd) ? x : x % modd));
}

int f[maxn];
void getf() { //递推
	f[1] = 0;
	for (int i = 2; i <= 5000000; i++) {
		f[i] = M(f[i / g[i]] + M(i * (g[i] - 1) / 2));
	}
	return ;
}

signed main() {
	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); //读入、输出优化
	
	cin >> t >> l >> r;
	
	prime();
	getf();
	poww = 1; //答案中的指数部分
	for (int i = l; i <= r; i++, poww = M(poww * t)) {
		ans = M(ans + M(poww * f[i])); //统计答案
	}
	
	cout << ans << '\n';
	
	return 0;
}
结语:十年 OI 一场空,不开 long long 见祖宗。

评论

0 条评论,欢迎与作者交流。

正在加载评论...