P6583 回首过去

Sol

答案一定形如 \(\frac{ac}{bc}\),其中 \(b\) 因子只有 \(2,5\)\(a\) 任意。

那么考虑枚举 \(c\),对应的方案数就是 \(\left\lfloor\frac{n}{c}\right\rfloor\times f(\left\lfloor\frac{n}{c}\right\rfloor)\),其中 \(f(x)\) 表示 \(x\) 以下只由 \(2,5\) 乘积组成的数的个数。

注意到除了 \(c\) 以外的项都是 \(\left\lfloor\frac{n}{c}\right\rfloor\) 相关的,所以直接数论分块。

Code

#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define pf push_front
#define desktop "C:\\Users\\incra\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
	if (y > x) return x = y,true;
	return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
	if (y < x) return x = y,true;
	return false;
}
LL power (LL a,LL b,LL p) {
	LL ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << (s) << endl
#define int LL
LL n;
LL a[10000010];
int count (int l,int r,int x) {
	// cout << "C   " << l << ' ' << r << ' ' << x << " " << r / x - (l - 1) / x << endl;
	return r / x - (l - 1) / x;
}
void mian () {
	cin >> n;
	int idx = 0;
	for (int i = 1;i <= n;i *= 2) {
		for (int j = i;j <= n;j *= 5) a[++idx] = j;
	}
	sort (a + 1,a + idx + 1);
	LL ans = 0;
	LL c1 = idx;
	for (int l = 1;l <= n;) {
		int r = n / (n / l);
		while (a[c1] > n / l) c1--;
		LL c2 = r - l + 1 - count (l,r,2) - count (l,r,5) + count (l,r,10);
		ans += c1 * c2 * (n / l);
		// cout << c2 << ' ' << c1 << ' ' << n / l << endl;
		l = r + 1;
	}
	cout << ans << endl;
}
signed main () {
	int T = 1;
	// cin >> T;
	while (T--) mian ();
	return 0;
}
posted @ 2025-05-20 20:21  incra  阅读(9)  评论(0)    收藏  举报