BZOJ2159 Crash的文明世界

Description

传送门
给你一个n个点的树,边权为1. 对于每个点u, 求:\(\sum_{i = 1}^{n} distance(u, i)^{k}\)
$ n \leq 50000, k \leq 150 $

Solution

咱们化一下式子:
\(\sum_{i = 1}^{n} distance(u,i) ^ {k}\)
\(=\sum_{i = 1}^{n} \sum_{j = 0}^{k} C(dis(u, i), j)* S2(k, j) * j!\)
\(=\sum_{j = 0}^{k} S2(k,j) * j! * \sum_{i = 1}^{n} C(dis(u, i), j)\)
\(dp[u][j] = \sum_{i = 1}^{n} C(dis(u, i), j)\)

那么设$down[u][j] $ 表示\(i \in subtree[u]\)的解, \(up[u][j]\)表示$ i \in tree - subtree[u]$的解

那么显然, 根据组合数性质:$${n \choose k} = {n - 1 \choose k} + {n - 1 \choose k - 1}$$

\[down[u][j] = down[son][j - 1] + down[son][j] \]

\[up[x][k]=up[x][k]+up[fa][k]+up[fa][k-1] \]

\[up[x][k]=up[x][k]+down[fa][k]+down[fa][k-1] \]

\[up[x][k]=up[x][k]-down[x][k]-down[x][k-1] \]

\[up[x][k]=up[x][k]-down[x][k-1]-down[x][k-2] \]

Codes

#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define Debug(s) debug("The massage in line %d, Function %s: %s\n", __LINE__, __FUNCTION__, s)
typedef long long LL;
typedef long double LD;
const int BUF_SIZE = (int)1e6 + 10;
struct fastIO {
    char buf[BUF_SIZE], buf1[BUF_SIZE];
    int cur, cur1;
    FILE *in, *out;
    fastIO() {
        cur = BUF_SIZE, in = stdin, out = stdout;
		cur1 = 0;
    }
    inline char getchar() {
        if(cur == BUF_SIZE) fread(buf, BUF_SIZE, 1, in), cur = 0;
        return *(buf + (cur++));
    }
    inline void putchar(char ch) {
        *(buf1 + (cur1++)) = ch;
        if (cur1 == BUF_SIZE) fwrite(buf1, BUF_SIZE, 1, out), cur1 = 0;
    }
    inline int flush() {
        if (cur1 > 0) fwrite(buf1, cur1, 1, out);
        return cur1 = 0;
    }
}IO;
#define getchar IO.getchar
#define putchar IO.putchar
int read() {
	char ch = getchar();
	int x = 0, flag = 1;
	for(;!isdigit(ch); ch = getchar()) if(ch == '-') flag *= -1;
	for(;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
	return x * flag;
}
void write(int x) {
	if(x < 0) putchar('-'), x = -x;
	if(x >= 10) write(x / 10);
	putchar(x % 10 + 48);
}
void putString(char s[], char EndChar = '\n') {
	rep(i, 0, strlen(s) - 1) putchar(*(s + i));
	if(~EndChar) putchar(EndChar);
}

#define Mod 10007
#define Maxn 50009
#define Maxk 159
struct edge {
	int to, nxt;
}g[Maxn << 1];
int n, k, head[Maxn], e, fac[Maxn], up[Maxn][Maxk], down[Maxn][Maxk], s[Maxk][Maxk];
namespace INIT {
	void add(int u, int v) {
		g[++e] = {v, head[u]}, head[u] = e;
	}
	void Main() {
		clar(head, -1);
		n = read(), k = read();
		rep(i, 1, n - 1) {
			int u = read(), v = read();
			add(v, u), add(u, v);
		}
		s[0][0] = 1;
		rep(i, 1, k)
			rep(j, 1, i) s[i][j] = (s[i - 1][j - 1] + j * s[i - 1][j]) % Mod;
		fac[0] = 1;
		rep(i, 1, k) fac[i] = fac[i - 1] * i % Mod;
	}
}
namespace SOLVE {
	int S[Maxn];
	void dfs(int u, int fa) {
		down[u][0] = 1;
		for(int i = head[u]; ~i; i = g[i].nxt) {
			int v = g[i].to;
			if(v != fa) {
				dfs(v, u);
				(down[u][0] += down[v][0]) %= Mod;
				rep(j, 1, k) (down[u][j] += (down[v][j] + down[v][j - 1]) % Mod) %= Mod;
			}
		}
	}
	void dfs1(int u, int fa) {
		for(int i = head[u]; ~i; i = g[i].nxt) {
			int v = g[i].to;
			if(v != fa) {
				up[v][0] = (n - down[v][0]) % Mod;
				rep(j, 1, k) {
					(up[v][j] += up[u][j - 1] + up[u][j]) %= Mod;
					(up[v][j] += down[u][j - 1] + down[u][j]) %= Mod;
					(up[v][j] -= (down[v][j - 1] + down[v][j - 2]) % Mod - Mod) %= Mod;
					(up[v][j] -= (down[v][j - 1] + down[v][j]) % Mod - Mod) %= Mod;
				}
				dfs1(v, u);
			}
		}
	}
	void Main() {
		dfs(1, 0), dfs1(1, 0);
		rep(i, 1, k) {
			int Tmp = fac[i] * s[k][i] % Mod;
			rep(j, 1, n) S[j] += (Tmp * (up[j][i] + down[j][i])) % Mod;
		}
		rep(i, 1, n) printf("%d\n", S[i] % Mod);
	}
}
int main() {
#ifdef Qrsikno
	freopen("BZOJ2159.in", "r", stdin);
	freopen("BZOJ2159.out", "w", stdout);
#endif
	INIT :: Main();
	SOLVE :: Main();
#ifdef Qrsikno
	debug("\nRunning time: %.3lf(s)\n", clock() * 1.0 / CLOCKS_PER_SEC);
#endif
	return IO.flush();
}
posted @ 2018-10-15 15:33  Qrsikno  阅读(256)  评论(4编辑  收藏  举报