• ACM_lowbit


    lowbit

    Time Limit: 2000/1000ms (Java/Others)

    Problem Description:

    long long ans = 0;
    for(int i = 1; i < = n; i ++)
        ans += lowbit(i)
    lowbit(i)的意思是将i转化成二进制数之后,只保留最低位的1及其后面的0,截断前面的内容,然后再转成10进制数
    比如lowbit(7),7的二进制位是111,lowbit(7) = 1,6 = 110(2),lowbit(6) = 2,同理lowbit(4) = 4,lowbit(12) = 4,lowbit(2) = 2,lowbit(8) = 8,每输入一个n,求ans
    

    Input:

    多组数据,每组数据一个n(1 <= n <= 5*10^8)

    Output:

    每组数据输出一行,对应的ans.

    Sample Input:

    1
    2
    3
    

    Sample Output:

    1
    3
    4
    解题思路:lowbit函数来源于树状数组,其含义是得到该数的二进制从右往左第一个非0位所表示的10进制数。这道题直接暴力枚举相加肯定是会超时的,因此需要推导一下有无求和公式。首先简单暴力输出前1000个数的lowbit值,其中int lowbit(int x){return x&-x;}发现有如下规律:
    1 3 5 7 9 ...... lowbit(i)=20
    2 6 10 14 18 ......lowbit(i)=21
    4 12 20 28 36 ......lowbit(i)=22
    8 24 40 56 72 ......lowbit(i)=23
    从上表中,可以知道每一行的lowbit值是相等的。
    拿n=9举个栗子:第一行有5个数,ans+=5*1,ans=5;第二行中有2个数,ans+=2*2,ans=9;第三行中有1个数,ans+=1*4,ans=13;第四行中有1个数,ans+=1*8,ans=21;求和完毕。现在的问题就是求解每一行有多少个lowbit值相等的数字,从所举栗子来看,假设p是所在行的lowbit值的指数,每一行有mp个数(数字的大小在n的范围内),则p=0时,m0=(9-20)/(20+1)+1=8/2+1=5;当p=1时,m1=(9-21)/(21+1)+1=7/4+1=2;当p=2时,m2=(9-22)/(22+1)+1=5/8+1=1;当p=3时,m3=(9-23)/(23+1)+1=1/16+1=1。而(int)log2(9)=3,即刚好枚举到p=3这一行,所以每一行在n的范围内相同lowbit值的数字求和公式为∑((n-2i)/(2i+1)+1)*2i,OK,推导完毕!
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int main()
     4 {
     5     int n;
     6     while(cin>>n){
     7         int p=log2(n);long long ans=0;
     8         for(int i=0;i<=p;++i)
     9             ans+=((n-(1<<i))/(1<<(i+1))+1)*(1<<i);
    10         cout<<ans<<endl;
    11     }
    12     return 0;
    13 }

     注意:左移<<运算符的优先级比双目运算符-还低,因此要加括号。

  • 相关阅读:
    C++之函数模板
    Boost库初见
    C++之异常处理
    C++之运行时类型识别RTTI
    Qt5.4静态编译方法
    Altium Designer极坐标布局方法
    PM2.5空气质量指数(AQI)是如何计算的
    emWin学习课堂
    uboot 下更改NAND的分区 fdisk
    gps 数据解析-NMEA 0183协议
  • 原文地址:https://www.cnblogs.com/acgoto/p/9033817.html
Copyright © 2020-2023  润新知