[NOIP1998 普及组] 阶乘之和
#include <bits/stdc++.h>
using namespace std;
const int m = 10;
struct ave
{
int a[5005], len;
void ass(int x)
{
int cnt = 0;
while(x > 0)
{
a[++ cnt] = x % m;
x /= m;
}
len = cnt;
}
ave operator * (ave b)
{
ave c;
for (int i = 1; i <= len + b.len; ++ i) c.a[i] = 0;
for (int i = 1; i <= len; ++ i)
{
for (int j = 1; j <= b.len; ++ j)
{
c.a[i + j - 1] += a[i] * b.a[j];
c.a[i + j] += c.a[i + j - 1] / m;
c.a[i + j - 1] = c.a[i + j - 1] % m;
}
}
if(c.a[len + b.len] != 0) c.len = len + b.len;
else c.len = len + b.len - 1;
return c;
}
ave operator + (ave b)
{
ave c;
int lenc = max(len, b.len);
for (int i = 1; i <= lenc + 1; ++ i) c.a[i] = 0;
for (int i = 1; i <= lenc; ++ i)
{
c.a[i] += b.a[i] + a[i];
c.a[i + 1] += c.a[i] / m;
c.a[i] %= m;
}
if(c.a[lenc + 1] > 0) lenc ++;
c.len = lenc;
return c;
}
};
ave calc(int n)
{
ave num, nume;
num.len = 1, num.a[1] = 1;
for (int i = 2; i <= n; ++ i)
{
nume.ass(i);
num = num * nume;
}
return num;
}
int main()
{
int n;
scanf("%d", &n);
ave num;
num.len = 0, num.a[1] = 0;
for (int i = 1; i <= n; ++ i) num = num + calc(i);
for (int i = num.len; i >= 1; -- i) printf("%d", num.a[i]);
return 0;
}