uoj450

题意

求有多少个长度为 \(n\) 的数组每个数都是 \([1,\ k]\),且每种数出现了 \(d\) 的倍数次。模 \(19491001\)

做法1

\([i\ =\ 0\ \bmod\ d]\ =\ \frac{1}{d}\ \sum_{j\ =\ 0}^{d\ -\ 1}\ \omega^{ij}\)

代码

#include <bits/stdc++.h>

#ifdef __WIN32
#define LLFORMAT "I64"
#else
#define LLFORMAT "ll"
#endif

using namespace std;

int main() {
	constexpr int mod = 19491001, A = 663067, B = 18827933;
	ios::sync_with_stdio(false);
	int n, k, d;
	cin >> n >> k >> d;
	auto pow_mod = [&](int x, int n) { int y = 1; while(n) { if(n & 1) y = (long long) y * x % mod; n >>= 1; if(n) x = (long long) x * x % mod; } return y; };
	if(d == 1) { cout << pow_mod(k, n) << endl; return 0; }
	if(d == 2) {
		int s = 0;
		for (int i = 0, C = 1; i <= k; ++i, C = (long long) C * (k - i + 1) % mod * pow_mod(i, mod - 2) % mod) {
			s = ((long long) C * pow_mod(2 * i - k, n) + s) % mod;
		}
		s = ((long long) s * pow_mod(2, (long long) (mod - 2) * k % (mod - 1)) % mod + mod) % mod;
		cout << s << endl;
		return 0;
	}
	int s = 0;
	for (int i = 0, C = 1; i <= k; ++i, C = (long long) C * (k - i + 1) % mod * pow_mod(i, mod - 2) % mod) {
		for (int j = 0, D = C; i + j <= k; ++j, D = (long long) D * (k - i - j + 1) % mod * pow_mod(j, mod - 2) % mod) {
			s = ((long long) D * pow_mod(((long long) i + (long long) A * j + (long long) B * (k - i - j)) % mod, n) + s) % mod;
		}
	}
	s = ((long long) s * pow_mod(3, (long long) (mod - 2) * k % (mod - 1)) % mod + mod) % mod;
	cout << s << endl;
	return 0;
}
posted @ 2019-01-15 15:46  King_George  阅读(236)  评论(0编辑  收藏  举报