题目2 : 二进制翻转

时间限制:20000ms
单点时限:1000ms
内存限制:256MB

描述

定义函数 Rev(x) 表示把 x 在二进制表示下翻转后的值

例如:

Rev(4)=1,因为 4 等于(100)B,翻转后是 (001)B,也就是 1

Rev(6)=3,因为 6 等于(110)B,翻转后是 (011)B,也就是 3

定义 Cnt(x) 表示 x 在二进制表示下 1 的个数,求:

输入

仅一行,一个非负整数 n

0 ≤ n ≤ 1015

输出

仅一行:一个非负整数表示答案

样例输入
2
样例输出
3
/*
Name: rev x& count num 1 of x in binary
Copyright: @2017 shenben
Author: shenben
Date: 25/04/17 16:47
Description:
//枚举当前要计算的数的位数,考虑从左右往中间dp
//f[i][j][k][cmp1][cmp2]表示考虑了前 i 位和后 i 位,前 i 位需要 j 个进位,后 i 位的进位为 k,前 i 位和后 i 位和上限的大小情况分别是 cmp1,cmp2
//转移时,同时枚举第 i+1 位和倒数第 i+1 位的值,枚举该位最后是否是 1 ,根据这个判断是否需要进位即可
//时间复杂度 O((logn)^2)
//(来自官方题解)
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=;
ll n,ans;int m,dig[N];
ll f[N][N][][][];
ll s[N][N][][][];
inline int fun(int b,int x,int y){
if(x==y) return b;
if(x<y) return ;
return ;
}
void solve(){
memset(f,,sizeof f);
memset(s,,sizeof s);
if(m==){ans++;return ;}
f[][][][fun(,,dig[])][]=;
f[][][][fun(,,dig[])][]=;
s[][][][fun(,,dig[])][]=;
s[][][][fun(,,dig[])][]=;
for(int i=;i<=m/;i++){
for(int j=;j<=m;j++){
for(int a=;a<;a++){
for(int b=;b<;b++){
for(int c=;c<;c++){
ll k=f[i-][j][a][b][c];
ll l=s[i-][j][a][b][c];
if(!k) continue;
//0,0
f[i][][a|(dig[m-i+]==)][fun(b,,dig[i])][]+=k;
s[i][][a|(dig[m-i+]==)][fun(b,,dig[i])][]+=l;
//0,1
f[i][j+][a|(dig[m-i+]==)][fun(b,,dig[i])][c]+=k;
s[i][j+][a|(dig[m-i+]==)][fun(b,,dig[i])][c]+=l+k*(-c);
if(a|(dig[m-i+]==)){
//1,0
f[i][j+][a][fun(b,,dig[i])][c]+=k;
s[i][j+][a][fun(b,,dig[i])][c]+=l+k*(-c);
//1,1
f[i][][a][fun(b,,dig[i])][]+=k;
s[i][][a][fun(b,,dig[i])][]+=l+k*(-j);
}
}
}
}
}
}
if(m&){
int i=m+>>;
for(int j=;j<=m;j++){
for(int a=;a<;a++){
for(int b=;b<;b++){
for(int c=;c<;c++){
ll k=f[i-][j][a][b][c];
ll l=s[i-][j][a][b][c];
if(!k) continue;
//
f[i][][a|(dig[m-i+]==)][b][]+=k;
s[i][][a|(dig[m-i+]==)][b][]+=l;
//
if(a|(dig[m-i+]==)){
f[i][][a][b][]+=k;
s[i][][a][b][]+=l+k*(-j);
}
}
}
}
}
}
int i=m+>>;
for(int j=;j<=m;j++){
for(int a=;a<;a++){
for(int b=;b<;b++){
for(int c=;c<;c++){
if(!a&&!b) continue;
ll k=f[i][j][a][b][c];
ll l=s[i][j][a][b][c];
if(!k) continue;
ans+=l;
if(c) ans-=k*j;
}
}
}
}
}
int main(){
cin>>n;
for(ll t=n;t;t>>=) dig[++m]=t&;
for(solve();--m;){
for(int i=;i<=m;i++) dig[i]=;
solve();
}
cout<<ans;
return ;
}

最新文章

  1. Java的流程控制和C++的异同
  2. KBMMW 4.93.10 win64 一个BUG 修正
  3. Java多线程简析
  4. Node.js入门:Node.js&amp;NPM的安装与配置
  5. thinkphp中limit方法
  6. 2016 Al-Baath University Training Camp Contest-1 G
  7. android 自动化压力测试-monkey 1 实践
  8. dojo 二 AMD模块
  9. OE中admin的内置帐号
  10. pt-query-digest分析mysql查询日志
  11. 如何在 PHP 中处理 Protocol Buffers 数据
  12. js解析XML
  13. Linux计划任务(转载)
  14. JDBC基础学习(四)&mdash;数据库事务
  15. Java语言的9个主要特性
  16. H5上传图片并使用canvas制作海报
  17. Netty实现客户端和服务端通信简单例子
  18. 阿里云API网关(3)快速入门(调用 API)
  19. pyqgis学习
  20. Retrofit2 项目配置

热门文章

  1. mysql 5.1超过默认8小时空闲时间解决办法(错误:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure)
  2. Hibernate与MyBatis的对比
  3. RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序”
  4. jquery click事件,多次执行
  5. SDK Manager.exe和AVD Manager.exe缺失,Android SDK Tools在检查java环境时卡住了,未响应卡死!
  6. Linux远程管理之SVN,VNC
  7. mysql中删除binlog的方法?mysql中如何删除binlog?
  8. linux中显示有颜色的字符
  9. Unity3D的按钮添加事件有三种方式
  10. js实现webSocket客户端