zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    驴的故事
    leetcode125. Valid Palindrome
    C#处理Excel的帮助类
    用SVN进行团队开发协作生命周期详解
    .net反编译原理
    科学使用Log4View2查看日志
    NLog日志框架使用探究-2
    NLog日志框架使用探究-1
    从零开始制作 NuGet 源代码包(全面支持 .NET Core / .NET Framework / WPF 项目)
    十分钟学会 Markdown 基本语法
  • 原文地址:https://www.cnblogs.com/gfc-g/p/3881293.html
Copyright © 2011-2022 走看看