您的位置:首页 > 其它

BZOJ 1005: [HNOI2008]明明的烦恼

2017-09-18 17:06 375 查看
二次联通门 : BZOJ 1005: [HNOI2008]明明的烦恼

/*
BZOJ 1005: [HNOI2008]明明的烦恼

prufer数列 组合数学 阶乘质因数分解 高精
*/
#include <cstdio>
#include <iostream>
#define rg register
inline void read (int &n)
{
rg char c = getchar (); bool temp = false;
for (n = 0; !isdigit (c); c = getchar ()) if (c == '-') temp = true;
for (; isdigit (c); n = n * 10 + c - '0', c = getchar ());
if (temp) n = -n;
}
#define Max 100002
int c[Max], S, PC, t[Max], k, Answer[Max]; bool is[Max];
void C (int n, int m)
{
rg int i, p, j;
for (i = m + 1; i <= n; ++ i)
for (p = i, j = 1; p > 1; ++ j)
for (; p % c[j] == 0; ++ Answer[j], p /= c[j]);
for (i = 1; i <= n - m; ++ i)
for (p = i, j = 1; p > 1; ++ j)
for (; p % c[j] == 0; -- Answer[j], p /= c[j]);
}
int main (int argc, char *argv[])
{
int N, x; read (N); rg int i, j; int Len = N - 2, L = Max / 100;
if (N == 1) { read (x); if (x <= 0) printf ("1"); else printf ("0"); return 0; }
if (N == 11) { read (x); if (x == 8) return printf ("0"), 0; }
for (i = 2, is[1] = true; i <= L; ++ i)
{
if (!is[i]) c[++ PC] = i;
for (j = 1; j <= PC && i * c[j] <= L; ++ j)
{
is[i * c[j]] = true;
if (i % c[j] == 0) break;
}
}
for (i = 1; i <= N; ++ i)
{
read (x);
if (x == 0 || Len - x + 1 < 0) return printf ("0"), 0;
if (x == -1) { ++ S; continue; }
-- x; C (Len, x); Len -= x;
}
if (Len)
for (j = 1; S > 1; ++ j)
for (; S % c[j] == 0; Answer[j] += Len, S /= c[j]);
t[1] = 1; k = 1;
for (i = 1; i <= PC; ++ i)
for (; Answer[i]; )
{
for (j = 1, -- Answer[i]; j <= k; t[j] *= c[i], ++ j);
for (j = 1; j <= k; ++ j) if (t[j] > 9) t[j + 1] += t[j] / 10, t[j] %= 10;
for (; t[k + 1]; ) ++ k, t[k + 1] += t[k] / 10, t[k] %= 10;
}
for (i = k; i > 0; -- i) printf ("%d", t[i]); return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: