列表

详情


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 这棵树的每个点的深度的平方和为 5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 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;
}

上一题