Maximum Set

先考虑第一问。

显然构造应该为 l,2×l,4×l,,2k×ll, 2 \times l, 4 \times l, \cdots, 2^k \times l,其中 2k×l<=r2^k \times l <= r2k+1×l>r2^{k+1} \times l > r,这里可以暴力枚举,显然 2k2^k 增长极快,所以暴力是一个 log\log 的。

另外就是第二问,考虑每一次,我们都是乘以 22,而导致不同方案但数量相同的就是不乘 22 而乘其他数。

我们可以证明这个其他数只能是 33,如果我们乘以 44 也可以达到最优数量,那么我们拆开乘以 2222 则更优。大于 44 同理。

所以我们只需要关心乘以 33

除此之外,第一个数除了选 ll,还可以选其他数,这也会导致更多的方案。

我们枚举最多乘以 33 的数量,算出此时 ll 的范围,设最多乘以 33 的数量为 ii 个,令 aa 为第一问的答案,那么这时总共需要乘 3i×2ai13^i \times 2^{a-i-1}1-1 是因为一开始的 ll 不算在内,可以求出 ll 的范围。

对于这一范围,贡献为 (ai)\dbinom{a}{i},逆元维护即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

#define int long long

int t, l, r;
const int N = 2e6 + 5, MOD = 998244353LL;
int fac[N];

long long qpow(long long a, long long b)
{
	int res = 1, base = a;
	while (b)
	{
		if (b & 1LL) 
		{
			res = res * base % MOD;
		}
		base = base * base % MOD;
		b >>= 1LL;
	}
	return res;
}

long long nqpow(long long a, long long b)
{
	int res = 1, base = a;
	while (b)
	{
		if (b & 1LL)
		{
			res = res * base;
		}
		base = base * base;
		b >>= 1LL;
	}
	return res;
}

#define inv(x) (qpow(x, MOD - 2))

inline long long C(int n, int m)
{
	return fac[n] * inv(fac[m]) % MOD * inv(fac[n - m]) % MOD;
}

signed main()
{
	scanf("%lld", &t);
	fac[0] = 1;
	for (int i = 1; i < N; i++)
	{
		fac[i] = fac[i - 1] * i % MOD;
	}
	while (t--)
	{
		scanf("%lld%lld", &l, &r);
		long long ans1 = 0LL, ans2 = 0LL, p = l;
		while (p <= r)
		{
			ans1++;
			p *= 2LL;
		}
		int last = l;
		for (int i = ans1 - 1; i >= 0; i--)
		{
			long long g = nqpow(3LL, i) * nqpow(2LL, ans1 - i - 1);
			if (r / g < l)
			{
				continue;
			}
			long long cg = C(ans1, i);
			ans2 += cg * (r / g - last + 1LL) % MOD;
			ans2 %= MOD;
			last = r / g + 1LL;
		}
		printf("%lld %lld\n", ans1, ans2);
	}
	return 0;
}
posted @   HappyBobb  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示