题目大意:
命
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)=x−1(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
k→2k+1 or k→2k
然后就是一颗二叉树
我们用倍增寻找
A
<
=
x
<
=
B
A<=x<=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));
}