【P1009】阶乘之和(高精求阶乘之和)

来源:互联网 发布:知乎液态金属散热 编辑:程序博客网 时间:2024/06/06 03:18


震惊!数组多开大一个10经惨遭TLE!
数组大小为1000010时100跑的慢死,但是为100010时秒杀!
究竟是%!¥#还是@¥#)

题目:

https://www.luogu.org/problem/show?pid=1009


跳过胡扯我们来看一下如何实现【一本正经】:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;typedef long long LL;#define RI register intconst int sz = 100010;inline void read(int &x){    x=0;bool fl=0;    char c=getchar();    while(c<'0'||c>'9')    {if(c=='-') fl=1;c=getchar();}    while(c>='0'&&c<='9')    {x=x*10+c-'0';c=getchar();}    if(fl) x*=-1;}inline void write(int x){    if(x<0) putchar('-'),x*=-1;    if(x/10) write(x/10);    putchar(x%10+'0');}int he[sz],num[sz],s[sz],n;inline void add(){    memset(he,0,sizeof(he));    he[0]=max(s[0],num[0]);    for(RI i=1;i<=he[0];++i)    {        he[i]+=s[i]+num[i];        he[i+1]=he[i]/10;        he[i]%=10;    }    while(he[ he[0]+1 ]>0)    {        he[ he[0]+2 ]=he[ he[0]+1 ]/10;        he[ he[0]+1 ]%=10;        he[0]++;    }    s[0]=he[0];    for(RI i=1;i<=he[0];++i)        s[i]=he[i];}int main(){    read(n);    num[0]=1,num[1]=1;    s[0]=1,s[0]=0;    for(RI k=1;k<=n;++k)    {        memset(he,0,sizeof(he));        he[0]=num[0];        for(RI i=1;i<=num[0];++i)        {            he[i]+=num[i]*k;            he[i+1]=he[i]/10;            he[i]%=10;        }        while(he[ he[0]+1 ]>0)        {            he[ he[0]+2 ]=he[ he[0]+1 ]/10;            he[ he[0]+1 ]%=10;            he[0]++;        }        for(RI i=1;i<=he[0];++i)            num[i]=he[i];        num[0]=he[0];        add();    }    for(RI i=s[0];i>=1;--i)        write(s[i]);    puts("");    return 0;}


s[0]和num[0]表示两个数组的长度
s表示答案,num表示阶乘,先算出阶乘,放在num里,再把s和它相加,更新s
主函数中初始化完毕后是高精乘法,在乘法中完成阶乘运算,用add进行高精加法表示s=s+a
处理好中间的进位后输出

原创粉丝点击