QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#323263#8211. Enumerating SubstringskarunaWA 213ms7636kbC++202.5kb2024-02-09 03:03:402024-02-09 03:03:40

Judging History

你现在查看的是最新测评结果

  • [2024-02-09 03:03:40]
  • 评测
  • 测评结果:WA
  • 用时:213ms
  • 内存:7636kb
  • [2024-02-09 03:03:40]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int MOD = 1e9 + 7;
struct mint {
	int x;
	mint() : x(0) {}
	mint(int x) : x(x) {}
	mint operator+(int ot) const { return x + ot >= MOD ? x + ot - MOD : x + ot; }
	mint operator-(int ot) const { return x < ot ? x - ot + MOD : x - ot; }
	mint operator*(int ot) const { return 1ll * x * ot % MOD; }
	mint operator+=(int ot) { return *this = *this + ot; }
	mint operator-=(int ot) { return *this = *this - ot; }
	mint operator*=(int ot) { return *this = *this * ot; }
	operator int() { return x; }
};
mint mpow(mint a, ll x) {
	mint r = 1;
	while (x) {
		if (x & 1) r *= a;
		a *= a;
		x /= 2;
	}
	return r;
}

mint binom(int n, int k) {
	mint r = 1;
	for (int i = 1; i <= k; i++) r *= i;
	r = mpow(r, MOD - 2);
	for (int i = n; i > n - k; i--) r *= i;
	return r;
}

mint pw[1010101];
int main() {
	mint n, m, k;
	cin >> n.x >> m.x >> k.x;
	pw[0] = 1;
	for (int i = 1; i < 1010101; i++) pw[i] = pw[i - 1] * k;

	mint ans = 0;
	mint acc = 0;
	for (int l = (m.x + 1) / 2; l <= m.x; l++) {
		if (k.x < m.x - l) continue;

		mint cnt = binom(k, m - l);
		for (int i = 1; i <= m - l; i++) cnt *= i;

		mint tot = 0;
		mint s = binom(k - (m - l), 2 * l - m);
		for (int i = 1; i <= 2 * l - m; i++) s *= i;

		for (int x = 0; x <= (2 * l - m) / 2; x++) {
			if (x < l - k.x) continue;
			tot += s;
			if (x != (2 * l - m) / 2) {
				s *= mpow(x + 1, MOD - 2);
				s *= (2 * l - m - 2 * x);
				s *= (2 * l - m - 2 * x - 1);
				s *= mpow(k - l + x + 1, MOD - 2);
				s *= mpow(2, MOD - 2);
			}
		}
		cnt *= tot;

		if (l != m.x) {
			acc += cnt;
		}
		else {
			cnt -= acc;
		}

		mint cur = 0;
		for (int r = 1; r <= (n.x - m.x + l) / l; r++) {
			int sz = r * l + (m.x - l);
			int rp = (l == m.x) ? r : (r + 1) / 2;

			int sx = 0;
			int ex = min(n.x - sz, l - 1);

			int sy = max(0, n.x - sz - l + 1);
			int ey = n.x - sz;

			if (ex < sy) {
				cur += pw[n.x - sz - l] * (ex - sx + 1 + ey - sy + 1) * (pw[l] - 1) * rp;
				cur += pw[n.x - sz - 2 * l] * (pw[l] - 1) * (pw[l] - 1) * (sy - ex - 1) * rp;
			}
			else {
				cur += pw[n.x - sz - l] * (pw[l] - 1) * (sy - sx + ey - ex) * rp;
				cur += pw[n.x - sz] * (ex - sy + 1) * rp;
			}
			//cout << sz << ' ' << "[" << sx << ", " << ex << "] " << "[" << sy << ", " << ey << "]\n";
		}
		//cout << l << ' ' << cnt << ' ';
		//cout << cur << endl;
		ans += cur * cnt;
	}
	cout << ans << '\n';
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3ms
memory: 7636kb

input:

4 2 3

output:

228

result:

ok 1 number(s): "228"

Test #2:

score: 0
Accepted
time: 213ms
memory: 7488kb

input:

999999 1999 12345678

output:

52352722

result:

ok 1 number(s): "52352722"

Test #3:

score: -100
Wrong Answer
time: 3ms
memory: 7540kb

input:

7 4 2

output:

999999999

result:

wrong answer 1st numbers differ - expected: '182', found: '999999999'