十分佩服DC学长,问他递推公式怎么得到的,他说他在纸上一划拉就划拉出来了,好吧。。。。。不过在他的指点下,还有题解的帮助下,我又仔细想了想,终于把这道题悟出来了。
1.一次递推出1——2,1——4,……1——2^k所需的步骤,这个可以找规律的。
k=1时,即1——2, 步数:0
k=2时,即1——4, 步数:1
k=3时,即1——8, 步数:4
k=4 时,即1——16, 步数:11
k=5时,即1——32, 步数: 26
可以发现1,4,11,26,后面一个比前一个大3,7,15,即2^(k-1)-1
2.求A到B的步数可以转化为1到B的步数减1到A的步数。
3.求1到a的步数如1——24.=(1——16)+(16——17)+(17——24) 而(17——24)就相当于1——8(24-16)。同样找规律可以发现2^k到2^k+1所需步数是k-1
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#define LL long long
using namespace std;
LL d[100]= {0};
void inlinee()
{
d[2]=1;
for(int i=3; i<=31; i++)
{
d[i]=d[i-1]+(1LL<<(i-1))-1;
}
}
LL comp(LL a)
{
LL ans=0;
for(int i=31; i>=0; i--)
{
if((1LL<<i)<=a)
{
ans+=d[i];
a-=(1LL<<i);
if(a>0) ans+=i-1;
}
}
return ans;
}
int main()
{
//freopen("in.txt","r",stdin);
LL start,end;
cin>>start>>end;
inlinee();
LL s=comp(start);
LL e=comp(end);
cout<<(s>e?s-e:e-s)<<endl;
return 0;
}