ural 1803

求Fibonacci的第n项K进制表示后各个位的和。

采用压缩的方式,表示成k ^ n进制,k ^ n < 1000000的,可以先预处理出来k ^ n各个数的位数之和。

然后直接采用模拟加法的方法进行计算。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 3000;

long long f[maxn];

struct Ans {
    int cnt_num;
    int order;
    bool operator < (const struct Ans &a) const {
        if (cnt_num == a.cnt_num) {
            return order < a.order;
        }
        return cnt_num < a.cnt_num;
    }
};

int sum[1000007];
struct Bign {
    int num[maxn];
    int num_len;
    int getAns() {
        int ret = 0;
        for (int i = 0; i < num_len; i++) {
            ret += sum[num[i]];
        }
        return ret;
    }
    Bign() {
        num_len = 0;
        memset(num, 0, sizeof(num));
    }
};
int n, k;
struct Bign a, b, c;
struct Ans ans[50007];
int mod;
int main() {
//    freopen("in.txt", "r", stdin);
    scanf("%d%d", &k, &n);
    mod = k;
    while (mod * k <= 1000000) {
        mod = mod * k;
    }
    for (int i = 0; i <= mod; i++) {
        int x = i;
        int temp = 0;
        while (x) {
            temp += x % k;
            x /= k;
        }
        sum[i] = temp;
    }
    a.num[0] = 1;
    a.num_len = 1;
    b.num[0] = 1;
    b.num_len = 1;
    ans[1].cnt_num = 1;
    ans[1].order = 1;
    ans[2].cnt_num = 1;
    ans[2].order = 2;
    for (int i = 3; i <= n; i++) {
        int pre = 0;
        int j;
        for (j = 0; j < a.num_len || j < b.num_len || pre; j++) {
            int next = (a.num[j] + b.num[j] + pre) % mod;
            c.num[j] = next;
            pre = (a.num[j] + b.num[j] + pre) / mod;
        }
        c.num_len = j;
        ans[i].order = i;
        ans[i].cnt_num = c.getAns();
        a = b;
        b = c;
    }
    sort(ans + 1, ans + 1 + n);
    for (int i = 1; i <= n; i++) {
        printf("%d ", ans[i].order);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值