2015-03-01 21:20:58
思路:这题的题意,简而言之就是给你n和k,让你求出前n个斐波那契数的各个数位上的数的和,进行排序后输出。
考虑,首先k的范围2~10,没有问题,但是n最大可达到50000,而斐波那契数的增长非常快,40+就能爆int。
所以要高精度+压位(不压位会T)
借用下贴吧里的题解:关于如何确定压位的进制,我们取满足:base = k^x <= 10^6,(x为整数)的最大base。这个可以暴力求得。
然后打表计算k进制下[0,base - 1]的各位数字和,剩下的就是高精度加法了。
※:关于如何比较快地打表计算,这里提供一种方法:
当前要计算a,那么:sum[a] = sum[a / k] + a % k
如果我们从0计算到base-1,那么在算a时,a/k必然算过,a/k比a少一位最低位,所以加上最低位a%k即可。
算法复杂度:O(10^6 + 1741 * 50000)<--(from 贴吧)
注意:这里可以用滚动数组,快速输出优化一下。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=1;i<=(n);++i) 17 #define REV(i,n) for(int i=(n);i>=1;--i) 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 20 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 21 #define MP(a,b) make_pair(a,b) 22 23 typedef long long ll; 24 typedef pair<int,int> pii; 25 const int INF = (1 << 30) - 1; 26 const int MAXN = 1000000; 27 28 int n,k; 29 int Base; 30 ll sum[MAXN + 10]; 31 32 void Write(int v){ 33 if(v>9) Write(v/10); 34 putchar(v%10+'0'); 35 } 36 37 struct BigInt{ 38 int len,s[3000]; 39 BigInt(){ len = 1; MEM(s,0); } 40 void clear(){ while(len > 1 && s[len - 1] == 0) --len; } 41 }bn[3]; 42 43 BigInt operator + (BigInt A,BigInt B){ 44 A.len = max(A.len,B.len); 45 for(int i = 0; i < A.len; ++i) A.s[i] += B.s[i]; 46 for(int i = 0; i < A.len; ++i) A.s[i + 1] += A.s[i] / Base,A.s[i] %= Base; 47 A.len++,A.clear(); 48 return A; 49 } 50 51 struct Node{ 52 ll num; 53 int id; 54 bool operator < (const Node& B) const{ 55 if(num == B.num) return id < B.id; 56 return num < B.num; 57 } 58 }nd[50010]; 59 60 int main(){ 61 scanf("%d%d",&k,&n); 62 Base = k; 63 while(Base < MAXN) Base *= k; 64 Base /= k; 65 for(int i = 0; i < Base; ++i) sum[i] = sum[i / k] + i % k; 66 int a = 0,b = 1,c = 2; 67 bn[a].s[0] = bn[b].s[0] = 1; 68 nd[1].num = nd[2].num = 1; 69 nd[1].id = 1; 70 nd[2].id = 2; 71 for(int i = 3; i <= n; ++i){ 72 bn[c] = bn[a] + bn[b]; 73 nd[i].num = 0; 74 nd[i].id = i; 75 for(int j = 0; j < bn[c].len; ++j) nd[i].num += sum[bn[c].s[j]]; 76 a = (a + 1) % 3; 77 b = (b + 1) % 3; 78 c = (c + 1) % 3; 79 } 80 sort(nd + 1,nd + n + 1); 81 for(int i = 1; i < n; ++i) Write(nd[i].id),putchar(' '); 82 Write(nd[n].id),putchar('\n'); 83 return 0; 84 }