【HDU】4919 Exclusive or 推公式+高精度

来源:互联网 发布:怎么在电脑上清理数据 编辑:程序博客网 时间:2024/05/22 04:50

传送门:【HDU】4919 Exclusive or


题目分析:本题主要是要推出公式来。

这是叉姐给的题解,为什么可以这样呢?主要是因为奇数和偶数异或总可以转化为两个偶数的异或再加1,而奇数和奇数异或总可以转化为两个偶数的异或,然后对所有数除以二就可以得到子函数了。4k-4是因为1异或n-1等于0异或n-2,因为n=2k,且1异或n-1等于n-1异或1,所以得到4k-4。

而且这个式子有一个特殊性,就是推的过程中最多同时只存在两个相邻的子式(k和k+1或k-1和k)。所以可以递归或者递推。用一个包含两个元素的数组可以轻易表达,我们让第一个元素总为f(k)的值,那么第二个元素总为f(k+1)。用类似快速幂的方法递推就行了。

倒是大数写的吐血。。。为了赋值方便还用了vector。。。


代码如下:


#include <cstdio>#include <cstring>#include <string>#include <vector>using namespace std ;#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define REV( i , a , b ) for ( int i = a ; i >= b ; -- i )#define CLR( a , x ) memset ( a , x , sizeof a )#define max( a , b ) ( ( a ) > ( b ) ? ( a ) : ( b ) )#define pb push_backconst int MAXN = 256 ;const int L = 10000 ;struct BigInt {int length , digit[MAXN] ;BigInt ( int number = 0 ) : length ( !!number ) {CLR ( digit , 0 ) ;digit[0] = number ;while ( length && digit[length - 1] >= L ) {digit[length] = digit[length - 1] / L ;digit[length - 1] %= L ;++ length ;}}BigInt fix () {while ( length && !digit[length - 1] )-- length ;return *this ;}int operator [] ( const int index ) const {return digit[index] ;}int & operator [] ( const int index ) {return digit[index] ;}BigInt operator = ( int number ) {CLR ( digit , 0 ) ;length = 0 ;while ( number ) {digit[length ++] = number % L ;number /= L ;}return *this ;}BigInt operator = ( const char *buf ) {CLR ( digit , 0 ) ;int len = strlen ( buf ) ;length = ( len -  1 ) / 4 + 1 ;REP ( i , 0 , len ) {int index = ( len - 1 - i ) / 4 ;digit[index] = digit[index] * 10 + buf[i] - '0' ;}return *this ;}BigInt operator + ( const BigInt &b ) const {BigInt c ;c.length = max ( ( *this ).length , b.length ) + 1 ;int add = 0 ;REP ( i , 0 , c.length ) {add += ( *this )[i] + b[i] ;c[i] = add % L ;add /= L ;}return c.fix () ;}BigInt operator - ( const int &b ) const {BigInt c ;c.length = ( *this ).length ;int del = -b ;REP ( i , 0 , ( *this ).length ) {del += ( *this )[i] ;c[i] = del ;del = 0 ;if ( c[i] < 0 ) {int tmp = ( -c[i] - 1 ) / L + 1 ;c[i] += tmp * L ;del = -tmp ;}}return c.fix () ;}BigInt operator * ( const BigInt &b ) const {BigInt c ;c.length = ( *this ).length + b.length ;REP ( i , 0 , ( *this ).length ) {int mul = 0 ;FOR ( j , 0 , b.length ) {mul += ( *this )[i] * b[j] + c[i + j] ;c[i + j] = mul % L ;mul /= L ;}}return c.fix () ;}BigInt operator / ( const int &b ) const {BigInt c ;c.length = ( *this ).length ;int over = 0 ;REV ( i , c.length - 1 , 0 ) {over = over * L + ( *this )[i] ;c[i] = over / b ;over %= b ;}return c.fix () ;}BigInt operator += ( const BigInt &b ) {*this = *this + b ;return *this ;}BigInt operator -= ( const int &b ) {*this = *this - b ;return *this ;}BigInt operator *= ( const BigInt &b ) {*this = *this * b ;return *this ;}BigInt operator /= ( const int &b ) {*this = *this / b ;return *this ;}bool operator < ( const BigInt &b ) const {if ( length != b.length )return length < b.length ;REV ( i , length - 1 , 0 )if ( digit[i] != b[i] )return digit[i] < b[i] ;return false ;}bool operator > ( const BigInt &b ) const {return b < *this ;}bool operator <= ( const BigInt &b ) const {return !( b < *this ) ;}bool operator >= ( const BigInt &b ) const {return !( *this < b ) ;}bool operator != ( const BigInt &b ) const {return b < *this || *this < b ;}bool operator == ( const BigInt &b ) const {return !( b < *this ) && !( *this < b ) ;}} ;char buf[500] ;void print ( const BigInt &res ) {printf ( "%d" , res[res.length - 1] ) ;REV ( i , res.length - 2 , 0 )printf ( "%04d" , res[i] ) ;printf ( "\n" ) ;}BigInt calculate ( const BigInt &a , const BigInt &n ) {BigInt res ;if ( n[0] & 1 )res = n / 2 * 6 ;elseres = n * 2 - 4 ;return res * a ;}void solve () {BigInt n , res = 0 ;n = buf ;std :: vector < BigInt > tmp ;tmp.pb ( 1 ) ;//ntmp.pb ( 0 ) ;//n + 1while ( n.length ) {res += calculate ( tmp[0] , n ) + calculate ( tmp[1] , n + 1 ) ;std :: vector < BigInt > new_tmp ;if ( n[0] & 1 ) {n /= 2 ;new_tmp.pb ( tmp[0] * 4 + tmp[1] * 2 ) ;//n / 2 - 1new_tmp.pb ( tmp[1] * 2 ) ;//n / 2}else {n = n / 2 - 1 ;new_tmp.pb ( tmp[0] * 2 ) ;//n / 2 - 1new_tmp.pb ( tmp[0] * 2 + tmp[1] * 4 ) ;//n / 2}tmp = new_tmp ;}print ( res ) ;}int main () {while ( ~scanf ( "%s" , buf ) )solve () ;return 0 ;}


0 0
原创粉丝点击