不知道哪里的题,用大数才过,简直丧心病狂!
Problem J
Bits
Input: Standard Input
Output: Standard Output
A bit is a binary digit, taking a logical value of either "1" or "0" (also referred to as "true" or "false" respectively). And every decimal number has a binary representation which is actually a series of bits. If a bit of a number is “1” and it's next bit is also “1” then we can say that the number has a 1 adjacent bit. And you have to find out how many times this scenario occurs for all numbers up to N.
Examples:
Number Binary Adjacent Bits
12 1100 1
15 1111 3
27 11011 2
Input
For each test case, you are given an integer number (0 <= N <= ((2^63)-2)), as described in the statement. The last test case is followed by a negative integer in a line by itself, denoting the end of input file.
Output
For every test case, print a line of the form “Case X: Y”, where X is the serial of output (starting from 1) and Y is the cumulative summation of all adjacent bits from 0 to N.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define mxn 100
#define inf 0x3f3f3f3f
#define eps 1e-8
#define LL long long
#define ull unsigned long long
#define MP make_pair
struct bign {
int x[1020], len;
bign(){
x[0] = 0, len = 0;
}
bign operator + ( const bign & b ) const {
int i, carry;
bign c;
for( i = carry = 0; i <= len || i <= b.len || carry; ++i ) {
if( i <= len )
carry += x[i];
if( i <= b.len )
carry += b.x[i];
c.x[i] = carry % 10;
carry /= 10;
}
c.len = i - 1;
return c;
}
bign operator + ( const LL& b ) const {
int i, carry = b;
bign c;
for( i = 0; i <= len || carry; ++i ) {
if( i <= len )
carry += x[i];
c.x[i] = carry % 10;
carry /= 10;
}
c.len = i - 1;
return c;
}
bign operator * ( const LL & b ) const {
int i, carry;
bign c;
for( i = carry = 0; i <= len || carry; ++i ) {
if( i <= len )
carry += b * x[i];
c.x[i] = carry % 10;
carry /= 10;
}
i --;
while( i && ! c.x[i] )
i--;
c.len = i;
return c;
}
void display() {
for( int i = len; i >= 0; -- i ) {
printf( "%d", x[i] );
}
}
}p[mxn], dp[mxn], sum[mxn], num[mxn];
// p[i] 表示2的i次方, dp[i]表示二进制位数为i+1的所有数的相邻1的对数和
// sun[i]表示 小于2的i+1次方的所有数的相邻1的对数和
// num[i]表示n的前i个位一共有多少数
int a[100];
void init() {
p[0] = p[0] + 1;
for( int i = 1; i < 64; ++i )
p[i] = p[i-1] * 2;
dp[1] = dp[1] + 1;
sum[1] = sum[1] + 1;
for( int i = 2; i < 64; ++i ) {
dp[i] = dp[i-1] * 2 + p[i-2];
sum[i] = sum[i-1] + dp[i];
}
}
int main() {
init();
LL n;
int cas = 1;
while( cin >> n && n >= 0 ) {
LL s = n;
int len = 0;
a[0] = 0;
while( s > 0 ) {
a[len++] = s % 2;
s >>= 1;
}
memset( num, 0, sizeof( num ) );
num[0] = num[0] + a[0] + 1;
for( int i = 1; i < len; ++i ) {
if( a[i] )
num[i] = num[i-1] + p[i];
else
num[i] = num[i-1];
}
bign ans;
for( int i = len - 1; i >= 0; --i ) {
if( i && a[i] )
ans = ans + sum[i-1];
if( i == len - 1 )
continue;
if( a[i] && a[i+1] )
if( i )
ans = ans + num[i-1];
else
ans = ans + 1;
}
printf( "Case %d: ", cas++ );
ans.display();
printf( "\n" );
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define mxn 100
#define inf 0x3f3f3f3f
#define eps 1e-8
#define LL long long
#define ull unsigned long long
#define MP make_pair
struct bign {
int x[1020], len;
bign(){
x[0] = 0, len = 0;
}
bign operator + ( const bign & b ) const {
int i, carry;
bign c;
for( i = carry = 0; i <= len || i <= b.len || carry; ++i ) {
if( i <= len )
carry += x[i];
if( i <= b.len )
carry += b.x[i];
c.x[i] = carry % 10;
carry /= 10;
}
c.len = i - 1;
return c;
}
bign operator + ( const LL& b ) const {
int i, carry = b;
bign c;
for( i = 0; i <= len || carry; ++i ) {
if( i <= len )
carry += x[i];
c.x[i] = carry % 10;
carry /= 10;
}
c.len = i - 1;
return c;
}
bign operator * ( const LL & b ) const {
int i, carry;
bign c;
for( i = carry = 0; i <= len || carry; ++i ) {
if( i <= len )
carry += b * x[i];
c.x[i] = carry % 10;
carry /= 10;
}
i --;
while( i && ! c.x[i] )
i--;
c.len = i;
return c;
}
void display() {
for( int i = len; i >= 0; -- i ) {
printf( "%d", x[i] );
}
}
}p[mxn], dp[mxn], sum[mxn], num[mxn];
// p[i] 表示2的i次方, dp[i]表示二进制位数为i+1的所有数的相邻1的对数和
// sun[i]表示 小于2的i+1次方的所有数的相邻1的对数和
// num[i]表示n的前i个位一共有多少数
int a[100];
void init() {
p[0] = p[0] + 1;
for( int i = 1; i < 64; ++i )
p[i] = p[i-1] * 2;
dp[1] = dp[1] + 1;
sum[1] = sum[1] + 1;
for( int i = 2; i < 64; ++i ) {
dp[i] = dp[i-1] * 2 + p[i-2];
sum[i] = sum[i-1] + dp[i];
}
}
int main() {
init();
LL n;
int cas = 1;
while( cin >> n && n >= 0 ) {
LL s = n;
int len = 0;
a[0] = 0;
while( s > 0 ) {
a[len++] = s % 2;
s >>= 1;
}
memset( num, 0, sizeof( num ) );
num[0] = num[0] + a[0] + 1;
for( int i = 1; i < len; ++i ) {
if( a[i] )
num[i] = num[i-1] + p[i];
else
num[i] = num[i-1];
}
bign ans;
for( int i = len - 1; i >= 0; --i ) {
if( i && a[i] )
ans = ans + sum[i-1];
if( i == len - 1 )
continue;
if( a[i] && a[i+1] )
if( i )
ans = ans + num[i-1];
else
ans = ans + 1;
}
printf( "Case %d: ", cas++ );
ans.display();
printf( "\n" );
}
return 0;
}