首页 > 代码库 > 【BZOJ 1005】无根树的Prufer数列
【BZOJ 1005】无根树的Prufer数列
今天看了Prufer数列这个东西。
每一个Prufer数列和无根树是一一对应的。所以求出有多少符合要求的Prufer数列即可。
点i在Prufer数列中的出现次数为i的度数 - 1。
代码如下:【用分解质因数的方法,避免了高精除】
#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <iostream>using namespace std;const int N = 10000 + 5, Prime_N = 1450 + 5;int n, Prime[Prime_N], A[N], p[Prime_N], Ans[N], P = 0, Bg, l, K;bool isPrime[N];void Add(int num, int Flag){ for (int i = 1; i <= P; i++) { if (Prime[i] > num) break; while (num % Prime[i] == 0) { p[i] += Flag; num /= Prime[i]; } }}void Cheng(int num){ for (int i = 1; i <= l; i++) Ans[i] *= num; for (int i = 1; i <= l; i++) { Ans[i + 1] += Ans[i] / 10; Ans[i] %= 10; } while (Ans[l + 1]) { l++; Ans[l + 1] += Ans[l] / 10; Ans[l] %= 10; }}int main(){ scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", A + i); for (int i = 1; i <= n; i++) isPrime[i] = true; isPrime[1] = false; for (int i = 2; i <= n; i++) { if (isPrime[i]) Prime[++P] = i; for (int j = 1; j <= P && i * Prime[j] <= n; j++) isPrime[i * Prime[j]] = false; } memset(p, 0, sizeof(p)); Bg = n - 2; K = n; for (int i = 1; i <= n; i++) { if (A[i] != -1) { K--; for (int j = 1; j <= A[i] - 1; j++) { Add(Bg, 1); Bg--; Add(j, -1); } } } Ans[1] = 1; l = 1; for (int i = 1; i <= P; i++) for (int j = 1; j <= p[i]; j++) Cheng(Prime[i]); for (int i = 1; i <= Bg; i++) Cheng(K); for (int i = l; i >= 1; i--) printf("%d", Ans[i]); printf("\n"); return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。