hihoCoder挑战赛28 题目2 : 二进制翻转
2024-10-05 03:20:43
题目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 ;
}
最新文章
- Java的流程控制和C++的异同
- KBMMW 4.93.10 win64 一个BUG 修正
- Java多线程简析
- Node.js入门:Node.js&;NPM的安装与配置
- thinkphp中limit方法
- 2016 Al-Baath University Training Camp Contest-1 G
- android 自动化压力测试-monkey 1 实践
- dojo 二 AMD模块
- OE中admin的内置帐号
- pt-query-digest分析mysql查询日志
- 如何在 PHP 中处理 Protocol Buffers 数据
- js解析XML
- Linux计划任务(转载)
- JDBC基础学习(四)&mdash;数据库事务
- Java语言的9个主要特性
- H5上传图片并使用canvas制作海报
- Netty实现客户端和服务端通信简单例子
- 阿里云API网关(3)快速入门(调用 API)
- pyqgis学习
- Retrofit2 项目配置
热门文章
- mysql 5.1超过默认8小时空闲时间解决办法(错误:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure)
- Hibernate与MyBatis的对比
- RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序”
- jquery click事件,多次执行
- SDK Manager.exe和AVD Manager.exe缺失,Android SDK Tools在检查java环境时卡住了,未响应卡死!
- Linux远程管理之SVN,VNC
- mysql中删除binlog的方法?mysql中如何删除binlog?
- linux中显示有颜色的字符
- Unity3D的按钮添加事件有三种方式
- js实现webSocket客户端