寻找k=2^n,使k为满足k<=i 中的最大值,
#include<iostream>
using namespace std;
int fun(int n)
{
int i,j;
j=2;
while(j<=n)
j*=2;
j/=2;
return j;
}
int main()
{
int i;
for(i=2;i<530;i++)
cout << i << " " << fun(i) << endl;
}
BD String
Accepts: 388
Submissions: 1164
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
等我写好,比赛都结束了,,最后在HDU上测试了一下 access!
个人发现,是这么个规律,,
1.第2^n 个位置,一定是B
2.假设j=2^n,j-i和j+i 位置都有字符
那么[j-i,j) 和 (j,j+i] 这两个区间内,或者B的数目等于前者D的数目,设前面的B 有x个,那么后面的B有 i+1-x 个.
3.[1 ~ (2^n)-1 ] 有2^(n-1)个B;
结合1 [1 ~ (2^n)] 有2^(n-1) +1 个B
#include<iostream>
#include <vector>
using namespace std;
int a[5] = {0,1,2,2,3};
long long fun(long long n)
{
long long j;
j=2;
while(j<=n)
j*=2;
j/=2;
return j;
}
long long OneToN(long long n)
{
if(n<=4)
return a[n];
long long sum=0;
long long j = fun(n);
//cout << j << " " << i << endl;
sum += j/2+1;
//cout << sum << endl;
if(n>j) sum += ((n-j)-(OneToN(j)-1-OneToN(j*2-n-1)));
return sum;
}
/*
int main()
{
for(long long i=1;i<=20;i++)
cout << i <<" " << OneToN(i)<< endl;
}
*/
int main()
{
int T;
long long l,r;
cin >> T;
while(T--)
{
cin >> l >> r;
cout << OneToN(r)-OneToN(l-1) << endl;
}
}