C. Maximum Set

C. Maximum Set

A set of positive integers S is called beautiful if, for every two integers x and y from this set, either x divides y or y divides x (or both).

You are given two integers l and r. Consider all beautiful sets consisting of integers not less than l and not greater than r. You have to print two numbers:

  • the maximum possible size of a beautiful set where all elements are from l to r;
  • the number of beautiful sets consisting of integers from l to r with the maximum possible size.

Since the second number can be very large, print it modulo 998244353.

Input

The first line contains one integer t (1t2104) — the number of test cases.

Each test case consists of one line containing two integers l and r (1lr106).

Output

For each test case, print two integers — the maximum possible size of a beautiful set consisting of integers from l to r, and the number of such sets with maximum possible size. Since the second number can be very large, print it modulo 998244353.

Example

input

4
3 11
13 37
1 22
4 100

output

2 4
2 6
5 1
5 7

Note

In the first test case, the maximum possible size of a beautiful set with integers from 3 to 11 is 2. There are 4 such sets which have the maximum possible size:

  • {3,6};
  • {3,9};
  • {4,8};
  • {5,10}.

 

解题思路

  先解决第一个问题,集合中最多可以有多少个数?不失一般性的,假设集合中的数从小到大为p, k1p, k1k2p, , k1kmpm+1个数,其中ki>1。很明显从集合中任取两个数,小的那个数一定能整除大的那个数。为了使得集合中的数尽可能多,我们很自然想到应该取尽可能小的ki,因此可以每个ki都取2,同时pl,那么此时集合中最大的数就是l2m,因此要满足l2mr,因此有mlogrl,因此m最大可以取到logrl

  按照上面的方法都已经取到集合数量的最大值了,为什么还会有多种方案呢?这是因为l不一定能整除r,意味着如果所有的ki都取2,在保证集合中有m+1个元素的前提下,p的取值不一定是l。实际上pr2m,因此p的取值范围是p[l,r2m]。这时就已经有r2ml+1种方案了。

  然后ki也不一定要全部取2,还可以将其中一个ki变成3。考虑一下如果某个ki4,那么我们可以把这个ki拆成22,集合中的元素会增加。因此每个ki3。如果有两个ki=3,那么我们那么我们把33拆成222,集合中的元素也会增加。因此最多只有一个ki=3

  对于有一个ki=3的情况,p的取值范围是p[l,r2m1 3],其中取3的位置有m个,因此这种情况就有(r2m1 3l+1)×m种方案。

  两种情况加起来,那么答案就是r2ml+1+(r2m13l+1)×m

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 void solve() {
 5     int l, r;
 6     scanf("%d %d", &l, &r);
 7     int m = __lg(r / l);
 8     printf("%d %d\n", m + 1, ((r >> m) - l + 1) + max(0, (r / 3 >> m - 1) - l + 1) * m);
 9 }
10 
11 int main() {
12     int t;
13     scanf("%d", &t);
14     while (t--) {
15         solve();
16     }
17     
18     return 0;
19 }
复制代码

 

参考资料

  Educational Codeforces Round 144 Editorial:https://codeforces.com/blog/entry/113408

posted @   onlyblues  阅读(68)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2022-03-03 乘积最大
Web Analytics
点击右上角即可分享
微信分享提示