1064 序列中最大的数 V3
有这样一个序列a:
a[0] = 0
a[1] = 1
a[2i] = a[i]
a[2i+1] = a[i] + a[i+1]
输入一个数N,求a[0] - a[n]中最大的数。
a[0] = 0, a[1] = 1, a[2] = 1, a[3] = 2, a[4] = 1, a[5] = 3, a[6] = 2, a[7] = 3, a[8] = 1, a[9] = 4, a[10] = 3。
例如:n = 5,最大值是3,n = 10,最大值是4。
输入
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
第2 - T + 1行:T个数,表示需要计算的n。(1 <= n <= 10^100)
输出
共T行,每行1个最大值。
输入样例
2
5
10
输出样例
3
4
这里就不给解析,只放代码:
c++代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
#define Z2 60
#define Z2H 30
#define M2 ((1LL << Z2) - 1)
#define M2H ((1LL << Z2H) - 1)
#define Z10 18
#define M10 1000000000000000000LL
#define MAXN (1LL << 60)
class bigint_2t;
class bigint_10t {
public:
bigint_10t() { memset( data, 0, sizeof(data) ); }
void assign( LL x ) { data[0] = ( x % M10 ); data[1] = (x / M10); }
void assign( bigint_10t& x ) {
memcpy( data, x.data, sizeof(data) );
}
void add( bigint_10t & x ) {
LL carry = 0;
for( int i = 0; i < 6; ++i ) {
data[i] = data[i] + x.data[i] + carry;
carry = (data[i] / M10);
data[i] %= M10;
}
}
bool operator <= ( bigint_10t& x ) {
for( int i = 5; i >= 0; --i ) {
if( data[i] < x.data[i] ) return true;
else if( data[i] > x.data[i] ) return false;
}
return true;
}
void read() {
char buf[128];
scanf( "%s", buf );
int len = strlen( buf );
int i = 0, k;
memset( data, 0, sizeof(data) );
while( len >= Z10 ) {
for( k = len - Z10; k < len; ++k ) data[i] = data[i] * 10 + buf[k] - '0';
++i; len -= Z10;
}
if( len > 0 ) {
for( k = 0; k < len; ++k ) data[i] = data[i] * 10 + buf[k] - '0';
}
}
void print() {
int i;
for( i = 5; i >= 0; --i ) if( data[i] > 0 ) break;
if( i == -1 ) printf( "0" );
else {
printf( "%I64d", data[i] );
for( --i; i >= 0; --i ) printf( "%018I64d", data[i] );
}
puts( "" );
}
void convert( bigint_2t& dst );
private:
LL data[6];
};
class bigint_2t {
friend class bigint_10t;
public:
bigint_2t() { memset( data, 0, sizeof(data) ); }
void assign( const LL x ) {
memset( data, 0, sizeof(data) );
data[0] = ( x & M2 ); data[1] = (x >> Z2);
}
void assign( const bigint_2t& x ) {
memcpy( data, x.data, sizeof(data) );
}
void assign_sum( const bigint_2t& x, const bigint_2t& y ) {
LL carry = 0;
for( int i = 0; i < 6; ++i ) {
data[i] = y.data[i] + x.data[i] + carry;
carry = (data[i] >> Z2);
data[i] &= M2;
}
}
void add( const bigint_2t & x ) {
LL carry = 0;
for( int i = 0; i < 6; ++i ) {
data[i] = data[i] + x.data[i] + carry;
carry = (data[i] >> Z2);
data[i] &= M2;
}
}
bool operator <= ( const bigint_2t& x ) {
for( int i = 5; i >= 0; --i ) {
if( data[i] < x.data[i] ) return true;
else if( data[i] > x.data[i] ) return false;
}
return true;
}
bool operator < ( const bigint_2t& x ) {
for( int i = 5; i >= 0; --i ) {
if( data[i] < x.data[i] ) return true;
else if( data[i] > x.data[i] ) return false;
}
return false;
}
void get_fusc( bigint_10t& ans ) {
bigint_10t a, b;
a.assign( 1 ); b.assign( 0 );
int i, j, k;
for( j = 5; j > 0; --j ) if( data[j] > 0 ) break;
for( i = 0; i < j; ++i ) {
for( k = 0; k < Z2; ++k ) {
if( data[i] & (1LL << k) ) b.add( a );
else a.add( b );
}
}
LL n = data[j];
while( n ) {
if( n & 1 ) b.add( a );
else a.add( b );
n >>= 1;
}
ans.assign( b );
}
void muladd( const bigint_2t& x, LL a ) {
LL carry = 0;
for( int i = 0; i < 6; ++i ) {
data[i] = (x.data[i] << 1) + carry;
carry = (data[i] >> Z2);
data[i] &= M2;
}
data[0] += a;
}
void print() {
int i;
for( i = 5; i >= 0; --i ) printf( "%I64d\n", data[i] );
}
private:
LL data[6];
};
void bigint_10t::convert( bigint_2t& dst ) {
dst.assign( 0 );
LL h1, l1, h2 = ( M10 >> Z2H ), l2 = ( M10 & M2H ), tmp, q, r = 0;
int i = 5, j, k = 0;
while( i >= 0 ) {
while( data[i] == 0 ) --i;
if( i < 0 ) break;
for( r = 0, j = i; j >= 0; --j ) {
h1 = r >> Z2H; l1 = r & M2H;
tmp = h1 * l2 + h2 * l1;
q = h1 * h2 + ( tmp >> Z2H );
r = ( ( tmp & M2H ) << Z2H ) + l1 * l2 + data[j];
q += ( r >> Z2 );
r &= M2;
data[j] = q;
}
dst.data[k++] = r;
}
}
struct stat_t {
int start_a;
int start_b;
int start_c;
void assign( int a, int b, int c ) {
start_a = a;
start_b = b;
start_c = c;
}
};
bigint_2t pos[42000];
int cnt = 0;
stat_t stat[334];
bigint_2t xbeg[334];
bigint_2t xend[334];
void init() {
int i;
xbeg[0].assign( 1 ); xend[0].assign( 1 );
for( i = 1; i < 334; ++i ) {
xbeg[i].muladd( xbeg[i-1], 0 );
xend[i].muladd( xend[i-1], ( ( i & 1 ) ? 1 : -1 ) );
}
stat[0].assign( cnt, cnt, cnt ); pos[cnt++].assign( 1 );
stat[1].assign( cnt, cnt, cnt ); pos[cnt++].assign( 3 );
stat[2].assign( cnt, cnt, cnt ); pos[cnt++].assign( 5 );
stat[3].assign( cnt, cnt, cnt + 1 ); pos[cnt++].assign( 9 ); pos[cnt++].assign( 11 );
stat[4].assign( cnt, cnt, cnt + 1 ); pos[cnt++].assign( 19 ); pos[cnt++].assign( 21 );
int a, b, c, x, y;
for( int lv = 5; lv < 334; ++lv ) {
a = stat[lv-3].start_a; b = stat[lv-3].start_b; c = stat[lv-3].start_c;
stat[lv].start_a = cnt; pos[cnt++].assign_sum( xbeg[lv], pos[a-1] );
stat[lv].start_b = cnt;
if( c - b > 2 ) x = ( lv & 1 ) ? c - 1 : c - 2;
else x = ( c - b > 0 ) ? c - 1 : b;
y = stat[lv-2].start_a;
while( x < y ) pos[cnt++].assign_sum( xbeg[lv], pos[x++] );
a = stat[lv-2].start_a; b = stat[lv-2].start_b; c = stat[lv-2].start_c;
stat[lv].start_c = cnt;
x = c - 1;
y = stat[lv-1].start_a;
while( x < y ) {
if( (lv & 3) == 1 && x == y - 2 ) { ++x; continue; }
pos[cnt++].assign_sum( xbeg[lv], pos[x++] );
}
}
}
int main() {
int t;
bigint_10t n, ans;
bigint_2t n2, one;
one.assign( 1 );
init();
scanf( "%d", &t );
while( t-- ) {
n.read();
n.convert( n2 );
n2.add( one );
lower_bound( pos, pos + cnt, n2 )[-1].get_fusc( ans );
ans.print();
}
return 0;
}
Java代码:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
public class Nod1064 {
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in), 1 << 16);
int t = Integer.parseInt(reader.readLine());
while (t-- > 0) {
System.out.println(solve(new BigInteger(reader.readLine())));
}
}
private static BigInteger solve(BigInteger n) {
if (n.compareTo(BigInteger.ONE.shiftLeft(1)) <= 0) {
return BigInteger.ONE;
}
if (n.bitCount() == 1) {
n = n.subtract(BigInteger.ONE);
}
if (n.bitCount() == n.bitLength()) {
return exFibnacc(BigInteger.ONE, BigInteger.ONE, n.bitLength() + 1);
}
int power = n.bitLength() - 1;
return max(
exFibnacc(BigInteger.ONE, BigInteger.ONE, power + 1),
solve(BigInteger.ONE, BigInteger.ONE,
n.subtract(BigInteger.ONE.shiftLeft(power)), power));
}
private static BigInteger solve(BigInteger left, BigInteger right,
BigInteger index, int power) {
if(index.bitCount() == 0) return left;
if (index.bitLength() >= power) {
if (left.compareTo(right) >= 0) {
return exFibnacc(left, left.add(right), power + 1);
} else {
return max(
exFibnacc(left, left.add(right), power + 1),
solve(right.add(left), right, index
.subtract(BigInteger.ONE.shiftLeft(power - 1)),
power - 1));
}
} else {
return solve(left, right.add(left), index, power - 1);
}
}
private static BigInteger max(BigInteger a, BigInteger b) {
return a.compareTo(b) > 0 ? a : b;
}
private static BigInteger exFibnacc(BigInteger first, BigInteger second,
int n) {
if(n == 1) return first;
BigInteger temp = second;
int size = n - 2;
while(size-- > 0){
temp = first.add(second);
first = second;
second = temp;
}
return temp;
}
}
Python2代码:
import re
N = 400
f = []
def calc():
global N
global f
f = [[0, 0] for i in xrange(N)]
f[1][0] = 1
f[1][1] = 0
f[2][0] = 0
f[2][1] = 1
for i in xrange(3, N):
f[i][0] = f[i - 1][0] + f[i - 2][0]
f[i][1] = f[i - 1][1] + f[i - 2][1]
def bisearch(ll, rr, cc, lv, rv):
global f
global n
mm = (ll + rr) / 2
mv = lv + rv
if mm <= n + 1:
if cc == 1:
ans = lv
elif lv < mv:
ans = lv * f[cc + 1][0] + mv * f[cc + 1][1]
else:
ans = mv * f[cc + 1][0] + lv * f[cc + 1][1]
if ll < mm and n >= mm:
ans = max(ans, bisearch(mm, rr, cc - 1, mv, rv))
else:
ans = bisearch(ll, mm, cc - 1, lv, mv)
return ans
def solve():
global f
global n
ll = 1
cc = 0
while (ll << 1) <= n:
ll <<= 1
cc += 1
rr = ll << 1
ans = f[cc + 1][0] + f[cc + 1][1]
ans = max(ans, bisearch(ll, rr, cc, 1, 1))
return ans
def main():
calc()
global n
t = int(raw_input())
for ti in xrange(t):
n = int(raw_input())
print(solve())
if __name__ == '__main__':
main()
Python3代码:
import heapq, bisect
maxn = 10 ** 100
f = {0 : 0, 1 : 1}
def F(x) :
if x in f :
return f[x]
if (x & 1) == 1 :
f[x] = F(x >> 1) + F((x + 1) >> 1)
else :
f[x] = F(x >> 1)
return f[x]
idx, val = [0], [F(0)]
que = [1]
while len(que) > 0 :
u = heapq.heappop(que)
fu = F(u)
if val[-1] >= fu :
continue
idx += [u]
val += [fu]
v = (u << 1) - 1
if v <= maxn :
heapq.heappush(que, v)
v = (u << 2) - 1
if v <= maxn :
heapq.heappush(que, v)
T = int(input())
for case in range(T) :
n = int(input())
i = bisect.bisect_right(idx, n)
print(val[i - 1])