题目大意:定义个一序列,f[i] = f[i / 2] (i % 2 == 0);f[i] = f[i / 2] + f[i / 2 + 1] (i % 2 == 1);求这个数列的第m项(m <= 10 ^ 100)
思路:数据范围高精度没跑了。记得之前做过这个题的弱化版,似乎是没有高精度的记忆化搜索,这个题就是加个高精度。
CODE:
#include <map> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 210 #define MO 10 using namespace std; #define max(a,b) ((a) > (b) ? (a):(b)) class BigInt{ private: int num[MAX],len; public: BigInt(int _ = 0) { memset(num,0,sizeof(num)); num[len = 1] = _; } void Read() { static char s[MAX]; scanf("%s",s); len = strlen(s); for(int i = 1; i <= len; ++i) num[i] = s[len - i] - '0'; } friend ostream &operator <<(ostream &os,const BigInt &a); bool operator <(const BigInt &a)const { if(len == a.len) { for(int i = len; i; --i) if(num[i] != a.num[i]) return num[i] < a.num[i]; } return len < a.len; } bool Odd()const { return num[1]&1; } BigInt operator +(const BigInt &a)const { BigInt re; re.len = max(len,a.len); int temp = 0; for(int i = 1; i <= re.len; ++i) { re.num[i] = temp + num[i] + a.num[i]; temp = re.num[i] / MO; re.num[i] %= MO; } if(temp) re.num[++re.len] = temp; return re; } BigInt operator /(int c)const { BigInt re; re.len = len; int temp = 0; for(int i = len; i; --i) { re.num[i] = (num[i] + temp) / 2; temp = (num[i] + temp) % 2 * MO; } while(!re.num[re.len]) --re.len; return re; } }temp; ostream &operator <<(ostream &os,const BigInt &a) { os << a.num[a.len]; for(int i = a.len - 1; i; --i) os << a.num[i]; return os; } map<BigInt,BigInt> G; int T; BigInt &MemorialSearch(const BigInt &a) { if(G.find(a) != G.end()) return G[a]; if(a.Odd()) G[a] = MemorialSearch(a / 2) + MemorialSearch(a / 2 + 1); else G[a] = MemorialSearch(a / 2); return G[a]; } int main() { G[0] = BigInt(0); G[1] = BigInt(1); for(cin >> T; T--;) { temp.Read(); cout << MemorialSearch(temp) << endl; } return 0; }
时间: 2024-10-14 01:20:38