JZOJ Day6 B组 T1 超级变变变

题目大意:

f ( x ) = x − 1 ( x   m o d   2 = 1 )   o r   x / 2 ( x   m o d   2 = 0 ) f(x) = x-1(x\ mod\ 2 = 1)\ or\ x/2(x\ mod\ 2 = 0) f(x)=x1(x mod 2=1) or x/2(x mod 2=0)
求区间 [ A , B ] [A, B] [A,B]中有多少个x满足经过若干次变化后变为k

解题思路:

我们反推一下,发现
k → 2 k + 1   o r   k → 2 k k \rightarrow 2k+1\ or\ k\rightarrow 2k k2k+1 or k2k
然后就是一颗二叉树
我们用倍增寻找 A &lt; = x &lt; = B A&lt;=x&lt;=B A<=x<=B

A c c e p t e d   c o d e : Accepted\ code: Accepted code:

#include<cstdio>
#include<algorithm>

using namespace std;

long long a, b, k, m_2[63];

long long Solve(long long Max) {
	if ((!k) || (k == 1)) return Max;
	long long now = 0;
	if (k & 1) {
		now += (Max >= k);
		for (int i = 1; k * m_2[i] <= Max; ++i)
			now += min(m_2[i], Max - k * m_2[i] + 1);
		return now;
	}
	now += (Max >= k) + (Max >= k+1);
	for (int i = 1; k * m_2[i] <= Max; ++i)
		now += min(m_2[i+1], Max - k * m_2[i] + 1);
	return now;
}

int main() {
	scanf("%lld %lld %lld", &k, &a, &b);
	m_2[0] = 1;
	for (int i = 1; i <= 62; ++i) m_2[i] = m_2[i-1] << 1;
	printf("%lld\n", Solve(b) - Solve(a-1));
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值