• acdream 1154 Lowbit Sum


    先贴代码,以后再写题解。。。

    首先,直接枚举肯定是会超时的,毕竟n就有10^9那么多。。。

    对于每个数,我们先把它转化为二进制;例:21-->10101;

    对于00001~10101,可以分为几个部分:

    00001~10000;

    10001~10100;

    10101

    因为对于每个数,从最右边的1截断,于是就可以理解为为:

    00001~10000:;

    001~100;

    1;

    设s[i]为二进制从右边数第 i+1 个数为1 (且其他数都为0)的lowbit sum;

    则 s[i]=s[i-1]*2+2^i-2^(i-1);

    则lowbit sum(21)=s[0]+s[2]+s[4];

    设i=4;即 10000;

    可分为 :

    00001~01000   s[i-1];

    01001~01111   s[i-1]-lowbit(01000)=s[i-1]-2^(i-1);  (从最右边的1截断,即可理解为 00001~00111 )

    10000       lowbit(10000)=2^i;

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 typedef long long ll;
     8 
     9 ll s[100];
    10 
    11 ll init (int n){
    12     if (s[n])
    13         return s[n];
    14     s[n]=init (n-1)*2-(1<<(n-1))+(1<<n);//cout<<s[n]<<" ";
    15     return s[n];
    16 }
    17 
    18 int main (){
    19     int n;    //while (cin>>n&&n) cout<<(1024>>n)<<endl;
    20     ll ans=1;
    21     int temp=2;
    22     memset (s,0,sizeof s);
    23     s[0]=1;
    24     init (30);    //for (int i=0;i<=30;i++) cout<<s[i]<<" ";
    25     while (~scanf ("%d",&n)){
    26         ans=0;
    27         for (int i=0;n&&i<30;i++) {
    28             if (n&1)
    29                 ans+=s[i];//cout<<ans<<endl;
    30             n>>=1;
    31             //n/=2;
    32         }
    33         printf ("%lld
    ",ans);
    34     }
    35     return 0;
    36 }
  • 相关阅读:
    SDN课程阅读作业(2)
    2019 SDN上机第5次作业
    第05组 Alpha事后诸葛亮
    第05组 Alpha冲刺(4/4)
    2020-4-5助教一周小结
    2020-3-29助教一周小结
    2020-3-22助教一周小结
    2020-03-15助教一周小结
    2020-03-08助教一周小结
    第一次个人编程作业(个人实现)
  • 原文地址:https://www.cnblogs.com/gfc-g/p/3881293.html
Copyright © 2020-2023  润新知