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 <= r 且 2k+1×l>r2^{k+1} \times l > r,这里可以暴力枚举,显然 2k2^k 增长极快,所以暴力是一个 log⁡\log 的。

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

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

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

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

我们枚举最多乘以 33 的数量,算出此时 ll 的范围,设最多乘以 33 的数量为 ii 个,令 aa 为第一问的答案,那么这时总共需要乘 3i×2a−i−13^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 @ 2023-06-15 21:43  HappyBobb  阅读(39)  评论(0)    收藏  举报  来源