找到使用2个设置位形成的第n个数字

时间:2017-01-26 07:32:04

标签: c++ algorithm

给定 n ,我需要找到只能用2位形成的第n个数字。

为了更好地澄清,序列基本上像3,5,6,9,10 ..

即。如果n = 1,则回答= 3等(注意答案必须以十进制形式打印)

以下是我根据我得到的答案所做的事情(对于一些隐藏的测试用例,它仍然给出了错误的答案)

using namespace std;

#define MAX 10000
#define MOD 1000000007

long long int m[MAX+1];
long long int sum;

long long int binary_search(long long int n)
{
   long long int low=0,high=MAX,mid;
   while(low<high)
   {
     mid=low+(high-low+1)/2;
     if(m[mid]<=n)
        low=mid;
     else
        high=mid-1;
   }
   return low;
}

int main() 
{
  m[0]=1;
  for(long long int i=1;i<=MAX;i++)
    m[i]=m[i-1]+i;

  long long int n,k,l;
  int t;
  scanf("%d",&t);
  for(int test=0;test<t;test++)
  {
    scanf("%lld",&n);
    k=binary_search(n);
    //cout<<m[k]<<" ";
    l=n-m[k];
    cout<<((1<<k+1)%MOD+(1<<l)%MOD)%MOD<<"\n";
  }
  return 0;
}

约束为1 <= T <= 10 ^ 6,1 <= N <= 10 ^ 14。

1 个答案:

答案 0 :(得分:2)

探索模式:

有一个有效数字,MSB(最高有效位)索引= 1 有两个有效数字,MSB(最高有效位)索引= 2 有三个有效数字,MSB(最高有效位)索引= 3(1001,1010,1100)
......

(MSB之后有k个位置,索引为k)

因此,您可以轻松找到给定n的MSB索引 - 只是利用算术级数的总和

当MSB = k已知时,减去AP之和直到k从n得到第二个非零位索引(l)

Result = (1 << k) + (1 << l)