3739. 数的变幻

单点时限: 1.0 sec

内存限制: 256 MB

Cuber QQ 正在刷 EOJ 上的水题,他正在做的一道题目是这样的。

给定一个正整数 x :

如果 x 是奇数的话,则变幻成 x−1 ;
如果 x 是偶数的话,则变幻成 x2 。
如此往复地执行这个操作,直到 x 变为 1 。

显然这对于 Cuber QQ 来说过于简单了。于是 Cuber QQ 根据这个发明了一个序列,称为变幻序列, x -变幻序列指的是,从 x 作为变幻的开始,一直变幻到 1 所构成的序列,例如 7 -变幻序列是 {7,6,3,2,1} ; 10 -变幻序列是 {10,5,4,2,1} 。

而现在 Cuber QQ 在纸上写出了所有 1 到 n 变幻序列,他分别统计了每一个数在这些序列中出现的次数,例如当 n=4 的时候,四个序列分别是 [1]={1},[2]={2,1},[3]={3,2,1},[4]={4,2,1} ,则 数 1 出现了 4 次,数 2 出现了 3 次 ,数 3 出现了 1 次 ,数 4 出现了 1 次。

现在 Cuber QQ 想知道最大的数 x 满足 x 在所有 1 到 n 变幻序列中至少出现了 k 次。

输入格式
第一行包含一个整数 T(1≤T≤104) ,表示数据组数。

对于每一组数据包含两个整数 n,k(1≤k≤n≤1018) ,含义如题面所述。

输出格式
对于每一组数据,输出一行一个整数表示答案。

样例
input
4
4 1
4 2
4 3
4 4
output
4
2
2
1
思路:对于每个数字 x 来说,它可以由自己变幻一次,也可以由某些更大的数字变幻得到。
简单的来说,当 x 是偶数时,x 会被 x+1 和 2x ,以及其2的整数倍变幻得到,即2x,2x+1,2x+2,2x+3,会发现对于每一个k,可以变换成x有:kx,kx+1…kx+2^k-1,当 x 是奇数的时候会被 x自己变幻一次,及2x,2x+1,归纳得到:kx,kx+1…kx+k-1。那么,很容易的发现,如果将奇数和偶数独立开来考虑的话,是满足单调性的。
于是我们考虑对奇数和偶数分别二分确定最大值,然后取两者中的较大值作为答案即可。
我们考虑对于每一个k,可以变幻为 x 的 k ∗ x + b 的最大个数,其中k为2的整数次幂。

k1242^m
x是奇数x2x,2x+14x,4x+1,4x+2,4x+3最多为2^m个
x是偶数x,x+12x,2x+1,2x+2,2x+34x,4x+1,4x+2…4x+7最多为2^(m+1)个
/*
考虑 x 是∈ [1,n],所以对于每一个 k,可以变幻为 x 的最大个数:
x是奇数:min(n-k*x,k-1)+1
x是偶数:min(n-k*x,2*k-1)+1
*/
#include<iostream>
#define ll long long
using namespace std;
ll n,k;
ll count=0;
ll f(ll x,ll k) {
	if(x*k>n)
		return 0;
	ll res=n-x*k;
	if(x%2==1)//奇数时
		return min(res,k-1)+1+f(x,k*2);
	else//偶数时
		return min(res,2*k-1)+1+f(x,k*2);
}
int main() {
	int t;
	cin>>t;
	while(t--) {
		cin>>n>>k;
		if(k==n)
			cout<<1<<endl;
		else if(k==n-1)
			cout<<2<<endl;
		else {
			ll l = 0,h = (n+2)/2;
			ll mid;
			while(h-l>1) {
				mid = (l+h)/2;
				ll p = f(mid*2,1);
				if(p<k)    h = mid;
				else    l = mid;
			}
			ll ans = f(l*2+1,1);
			if(ans>=k)   
			   printf("%lld\n",l*2+1);
			else    
			   printf("%lld\n",l*2);
		}

	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值