洛谷【P1009】阶乘之和

题目传送门:https://www.luogu.org/problemnew/show/P1009

高精度加法:https://www.cnblogs.com/AKMer/p/9722610.html

之所以在运算法则这个分组的最后一篇博客写这道题是因为之前没写过高精乘低精,也没讲过压位。

所谓压位,就是每一位不只存一位数,比如\(1000009\)分成\(1\)\(0\)\(9\)来存,就只需要三位就能存了。然后\(10\)进制改成\(1000\)进制就行了。

时间复杂度:\(O(len^2)\)

空间复杂度:\(O(len)\)

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int pps=1000;

int n;

int read() {
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return x*f;
}

struct Bignum {
    int num[54];

    void clear() {
        memset(num,0,sizeof(num));
        num[0]=num[1]=1;
    }

    Bignum operator*(const int &a)const {
        Bignum c;memset(c.num,0,sizeof(c.num));
        c.num[0]=num[0];
        for(int i=1;i<=num[0];i++) {
            c.num[i]+=num[i]*a;
            c.num[i+1]+=c.num[i]/pps;
            c.num[i]%=pps;
        }
        if(c.num[c.num[0]+1])c.num[0]++;
        return c;
    }//高精乘低精

    Bignum operator+(const Bignum &a)const {
        Bignum c;memset(c.num,0,sizeof(c.num));
        c.num[0]=max(num[0],a.num[0]);
        for(int i=1;i<=c.num[0];i++) {
            c.num[i]+=num[i]+a.num[i];
            c.num[i+1]+=c.num[i]/pps;
            c.num[i]%=pps;//pps进制,直接强上就行了。
        }
        if(c.num[c.num[0]+1])c.num[0]++;
        return c;
    }

    void print() {
        printf("%d",num[num[0]]);
        for(int i=num[0]-1;i>0;i--)
            printf("%03d",num[i]);//记得不足3为前导补0
    }
}ans;

int main() {
    n=read();
    for(int i=1;i<=n;i++) {
        Bignum res;res.clear();
        for(int j=1;j<=i;j++)
            res=res*j;//算阶乘
        ans=ans+res;//累加
    }ans.print();
    return 0;
}

转载于:https://www.cnblogs.com/AKMer/p/9726688.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值