NC219769. NIT的树
描述
NIT 在 n 年前还是普及组选手的时候做过这样一个题目,给你一棵树,求这棵树的所有点的深度之和,以NIT现在国家队的实力,做这样的题实在是太侮辱他的智商了,于是他思考着加强这道题目。
他现在让你求出,所有 n 个点的有标号有根树的每个点深度的 m 次方的和,令根的深度为 1 。
输出对 取模的结果。
输入描述
一行两个整数 n,m
输出描述
输出一行 1 个数,表示所有 n 个点的有标号有根树的每个点的深度的 m 次方之和,对 取模。
示例1
输入:
2 1
输出:
6
说明:
总共有 2 种不同的树,1->2 这棵树的每个点的深度和为 3,2->1 这棵树的每个点的深度和为 3示例2
输入:
2 2
输出:
10
说明:
总共有 2 种不同的树,1->2 这棵树的每个点的深度的平方和为 5,2->1 这棵树的每个点的深度的平方和为 5C++ 解法, 执行用时: 1246ms, 内存消耗: 78592K, 提交时间: 2021-06-20 09:49:41
#include <bits/stdc++.h> using namespace std; using ll = long long; const int mod = 421969921; const int maxn = 10000100; int fac[maxn], ifac[maxn]; int qpow(int a, int n) { int ans = 1; for ( ; n; n>>=1, a=(ll)a*a%mod) if (n&1) ans=(ll)ans*a%mod; return ans; } int main(void) { int n; ll m; scanf("%d%lld", &n, &m); m %= (mod - 1); fac[0] = 1; for (int i=1; i<=n; i++) fac[i] = fac[i-1] * (ll)i % mod; ifac[n] = qpow(fac[n], mod - 2); for (int i=n-1; i>=0; i--) ifac[i] = ifac[i+1] * (ll)(i+1) % mod; int f = 1, ans = qpow(n, m); for (int i=n-1; i>=1; i--) { ans = (ans + qpow(i, m + 1) * (ll)f % mod * ifac[n - i]) % mod; f = f * (ll)n % mod; } ans = (ll)ans * fac[n] % mod; printf("%d\n", ans); return 0; }