QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#31290#4011. 计算几何Qingyu60 617ms28036kbC++235.1kb2022-05-06 13:33:472022-05-06 13:33:49

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-05-06 13:33:49]
  • 评测
  • 测评结果:60
  • 用时:617ms
  • 内存:28036kb
  • [2022-05-06 13:33:47]
  • 提交

answer

#include <bits/stdc++.h>

const int mod = 998244353;
const int inv2 = (mod + 1) / 2;
inline int inc(int x, int y) { x += y - mod; return x + (x >> 31 & mod); }
inline int dec(int x, int y) { x -= y; return x + (x >> 31 & mod); }
inline int mul(int x, int y) { return 1ll * x * y % mod; }
inline void addmul(int &x, int y, int z) {
	x = (x + 1ll * y * z) % mod;
}
inline void upd(int &x, int y) { x = inc(x, y); }
inline void pud(int &x, int y) { x = mul(x, y); }

inline int fastpow(int x, long long p) {
	int r = 1;
	while (p) {
		if (p & 1) pud(r, x);
		pud(x, x);
		p >>= 1;
	}
	return r;
}

void bruteforce(int a, int b, int c) {
	std::vector<int> x, y;
	int tot = 0;
	for (int i = -2 * a + 1; i <= 2 * a - 1; ++i)
		for (int j = -2 * b + 1; j <= 2 * b - 1; ++j)
			if (-2 * c + 1 <= i + j && i + j <= 2 * c - 1) {
				if (i % 2 || j % 2) {
					tot++;
					x.push_back(i);
					y.push_back(j);
				}
			}
	int mx = 0, ways = 0;
	const int dx[6] = { 0, 0, 1, -1, 1, -1 };
	const int dy[6] = { 1, -1, 0, 0, -1, 1 };
	auto adjacent = [&](int i, int j) {
		for (int o = 0; o < 6; ++o)
			if (x[i] + dx[o] == x[j] && y[i] + dy[o] == y[j])
				return true;
		return false;
	};
	for (int mask = 0; mask < (1 << tot); ++mask) {
		int t = __builtin_popcount(mask);
		if (t < mx)
			continue;
		bool ok = true;
		for (int i = 0; i < tot; ++i)
			if (mask >> i & 1)
				for (int j = 0; j < i; ++j)
					if (mask >> j & 1)
						if (adjacent(i, j)) {
							ok = false;
							break;
						}
		if (!ok) continue;
		if (t == mx) ++ways;
		else {
			mx = t;
			ways = 1;
		}
	}
	printf("%d %d\n", mx, ways);
}

struct state_t {
	int mx, ways;
	state_t() : mx(-1), ways(0) {
	}
	state_t(int mx, int ways) : mx(mx), ways(ways) {

	}
};
state_t operator+(const state_t &lhs, const state_t &rhs) {
	int mx = std::max(lhs.mx, rhs.mx);
	int ways = 0;
	if (lhs.mx == mx)
		ways = lhs.ways;
	if (rhs.mx == mx)
		upd(ways, rhs.ways);
	return state_t(mx, ways);
}
const int K = 15;
state_t dp[2][1 << K];
int popcnt[1 << K];

void init() {
	for (int i = 0; i < (1 << K); ++i)
		popcnt[i] = popcnt[i >> 1] + (i & 1);
}

void solve(int a, int b, int c) {
	unsigned even_mask = 0;
	for (int i = 0; i < 30; i += 2)
		even_mask |= 1u << i + 1;
	auto row_valid = [&](int mask) {
		return (mask & (mask >> 1)) == 0;
	};
	auto trans_valid = [&](int mask1, int mask2) {
		return (mask1 & mask2) == 0 && (mask1 & (mask2 << 1)) == 0;
	};
	// -2 * c + 1 <= x + y <= 2 * c - 1
	// -2 * c + 1 - y <= x <= 2 * c - 1 - y
	auto get_left = [&](int y) {
		return std::max(-2 * a + 1, -2 * c + 1 - y);
	};
	auto get_right = [&](int y) {
		return std::min(2 * a - 1, 2 * c - 1 - y);
	};
	auto get_full_mask = [&](int l, int r) -> unsigned {
		if (l > r) return 0;
		l += 2 * a - 1, r += 2 * a - 1;
		// 0 <= l <= r <= 4 * a - 2
		unsigned tmask = 0;
		for (int i = l; i <= r; ++i)
			tmask |= 1 << i;
		return tmask;
	};
	int o = 0;
	//dp[o][0] = state_t(0, 1);
	
	int total = 4 * a - 1, trans_total = 0;
	std::vector<int> all_valid_masks;
	std::vector<std::vector<int>> valid_trans(1 << total);
	for (int i = 0; i < (1 << total); ++i) {
		if (row_valid(i)) {
			all_valid_masks.push_back(i);
		}
	}
	for (int mask1 : all_valid_masks)
		for (int mask2 : all_valid_masks)
			if (trans_valid(mask1, mask2) && ((mask1 & even_mask) == 0 || (mask2 & even_mask) == 0)) {
				valid_trans[mask1].push_back(mask2);
				++trans_total;
			}
	
	state_t ans(-1, 0);
	for (int mask : all_valid_masks)
		dp[o][mask] = state_t(popcnt[mask], 1);
	for (int y = -2 * b + 1; y <= 2 * b - 1; ++y) {
		for (int i : all_valid_masks)
			dp[!o][i] = state_t(-1, 0);
		int left_x = get_left(y), right_x = get_right(y);
		int full_mask = get_full_mask(left_x, right_x);	
		for (int mask = full_mask; ; mask = (mask - 1) & full_mask) if (dp[o][mask].mx != -1) {
			if (mask) {
				ans = ans + dp[o][mask];
			}
			if (!row_valid(mask))
				continue;
			if (y % 2 == 0 && (mask & even_mask) != 0)
				continue;
			for (int next_mask : valid_trans[mask]) {
				dp[!o][next_mask] = dp[!o][next_mask] + state_t(dp[o][mask].mx + popcnt[next_mask], dp[o][mask].ways);
			}
			if (!mask) break;
		}
		o = !o;
	}
	printf("%d %d\n", ans.mx, ans.ways);
}
const int N = 3e6 + 50;
int fact[N], inv[N];
bool has_calced_fact = false;
void calc(int n) {
	fact[0] = 1;
	for (int i = 1; i <= n; ++i)
		fact[i] = mul(i, fact[i - 1]);
	inv[n] = fastpow(fact[n], mod - 2);
	for (int i = n - 1; i >= 0; --i)
		inv[i] = mul(i + 1, inv[i + 1]);
}
void solve_equal(int a, int b, int c) {
	if (!has_calced_fact) {
		calc(N - 1);
		has_calced_fact = true;
	}
	int n = a;
	int64_t max = 3ll * n * n;
	int ways = 1;
	for (int i = 0; i < n; ++i) {
		pud(ways, fact[i]);
		pud(ways, fact[i + 2 * n]);
		pud(ways, inv[i + n]);
		pud(ways, inv[i + n]);
	}
	printf("%lld %d\n", max, ways);
}

int main() { 
	init();
	int T;
	scanf("%d", &T);
	while (T--) {
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		if (a == b && b == c)
			solve_equal(a, b, c);
		else
			solve(a, b, c);
	}
}


详细

Test #1:

score: 5
Accepted
time: 24ms
memory: 27904kb

input:

9
3 3 3
1 1 1
3 3 3
1 1 1
3 3 3
2 2 2
3 3 3
2 2 2
3 3 3

output:

27 980
3 2
27 980
3 2
27 980
12 20
27 980
12 20
27 980

result:

ok 9 lines

Test #2:

score: 5
Accepted
time: 26ms
memory: 27904kb

input:

10
4 4 4
3 3 3
1 1 1
2 2 2
4 4 4
4 4 4
2 2 2
4 4 4
4 4 4
3 3 3

output:

48 232848
27 980
3 2
12 20
48 232848
48 232848
12 20
48 232848
48 232848
27 980

result:

ok 10 lines

Test #3:

score: 5
Accepted
time: 41ms
memory: 28036kb

input:

10
1 2 2
1 2 4
3 1 3
3 3 1
4 3 4
4 4 4
1 4 2
1 1 1
3 3 3
3 4 4

output:

7 4
8 1
11 6
11 6
39 14112
48 232848
8 1
3 2
27 980
39 14112

result:

ok 10 lines

Test #4:

score: 5
Accepted
time: 23ms
memory: 4536kb

input:

10
3 100 100
3 98 100
3 45 54
3 56 57
3 79 80
3 99 97
3 2 2
3 5 8
3 89 87
3 95 95

output:

1191 386990672
1175 539161334
540 1
668 597802742
944 88504157
1163 413653028
15 20
60 1
1043 408813607
1131 489761860

result:

ok 10 lines

Test #5:

score: 5
Accepted
time: 148ms
memory: 4544kb

input:

10
3 1000 1000
3 998 1000
3 450 540
3 569 570
3 799 800
1 999 999
3 200 200
3 797 800
2 984 985
2 797 797

output:

11991 368456334
11975 319484294
5400 1
6824 270662241
9584 777832912
3995 1998
2391 688129042
9564 1
7871 274044687
6372 931624591

result:

ok 10 lines

Test #6:

score: 5
Accepted
time: 156ms
memory: 4456kb

input:

10
3 999 999
3 899 897
3 799 800
1 314 314
3 599 299
2 924 925
3 569 570
3 980 980
3 797 800
2 797 797

output:

11979 143556225
10763 789509419
9584 777832912
1255 628
3588 1
7391 55315847
6824 270662241
11751 764285985
9564 1
6372 931624591

result:

ok 10 lines

Test #7:

score: 5
Accepted
time: 617ms
memory: 6268kb

input:

10
3 2831 2832
3 3641 3641
2 4958 4958
2 4757 4756
1 4234 4234
3 1294 1296
3 4865 3857
3 4598 4596
3 2 2
3 4983 4984

output:

33968 222796211
43683 991035937
39660 138057687
38047 734317385
16935 8468
15527 296868897
46284 1
55151 574369882
15 20
59792 628461191

result:

ok 10 lines

Test #8:

score: 5
Accepted
time: 613ms
memory: 4460kb

input:

10
3 3795 3795
1 4353 4353
2 981 981
3 3865 3866
3 1998 1999
3 2345 2347
3 4759 4756
2 1245 1246
2 2385 3845
3 3771 3770

output:

45531 954169403
17411 8706
7844 23006980
46376 582135734
23972 914547013
28139 341107126
57072 1
9959 579653674
19080 1
45236 589619316

result:

ok 10 lines

Test #9:

score: 5
Accepted
time: 35ms
memory: 27888kb

input:

10
24 24 24
42 42 42
77 77 77
17 17 17
59 59 59
15 15 15
90 90 90
47 47 47
75 75 75
20 20 20

output:

1728 252553554
5292 380589438
17787 42131906
867 739254462
10443 743809195
675 905920394
24300 754508597
6627 697962640
16875 698790321
1200 955417590

result:

ok 10 lines

Test #10:

score: 5
Accepted
time: 24ms
memory: 27904kb

input:

10
37 37 37
46 46 46
43 43 43
19 19 19
49 49 49
9 9 9
17 17 17
92 92 92
50 50 50
100 100 100

output:

4107 893875715
6348 563300886
5547 881523094
1083 18413628
7203 426655263
243 768718993
867 739254462
25392 628099022
7500 962679491
30000 951252372

result:

ok 10 lines

Test #11:

score: 0
Runtime Error

input:

10
73 48 54
59 50 76
61 26 86
37 82 65
47 85 41
59 67 41
95 9 100
83 36 13
45 69 38
98 75 88

output:


result:


Test #12:

score: 0
Runtime Error

input:

10
97 64 36
37 33 62
44 31 31
5 59 28
20 65 78
16 16 12
79 79 8
40 94 58
79 70 10
19 54 20

output:


result:


Test #13:

score: 0
Memory Limit Exceeded

input:

10
47 53 38
49 75 90
64 18 30
68 68 25
64 23 81
91 30 54
34 63 26
56 88 86
98 95 71
72 26 90

output:


result:


Test #14:

score: 0
Runtime Error

input:

10
37 44 98
19 26 35
36 16 4
92 23 40
38 36 84
55 78 82
47 49 30
94 70 28
32 14 22
56 29 81

output:


result:


Test #15:

score: 5
Accepted
time: 26ms
memory: 27908kb

input:

10
34401 34401 34401
98651 98651 98651
78629 78629 78629
65591 65591 65591
66046 66046 66046
52700 52700 52700
17307 17307 17307
33324 33324 33324
77617 77617 77617
99785 99785 99785

output:

3550286403 992487865
29196059403 420763712
18547558923 153343492
12906537843 81352952
13086222348 650486915
8331870000 97517555
898596747 225446043
3331466928 76350604
18073196067 435310816
29871138675 202468820

result:

ok 10 lines

Test #16:

score: 0
Memory Limit Exceeded

input:

10
3647 74898 74991
51941 70217 44785
51153 1620 52094
62267 51597 11976
65243 26874 45053
34401 98651 78629
65591 23554 66046
52700 17307 53332
77617 99785 74174
60382 17109 62860

output:


result:


Test #17:

score: 0
Runtime Error

input:

10
308 316 10
403 6 400
3 576 570
587 2 586
1000 1000 1
1 1 1000000
100 100 100
113 80 110
1000000 1 1
1 1000000 1

output:


result:


Test #18:

score: 0
Runtime Error

input:

10
970 1 970
385 380 6
2 700 706
101 100 99
183 24 202
999999 1 1
1 1 999999
4 124830 2
832 2 12
133 77 77

output:


result:


Test #19:

score: 5
Accepted
time: 118ms
memory: 27896kb

input:

10
201572 201572 201572
590217 590217 590217
374643 374643 374643
92508 92508 92508
1000000 1000000 1000000
247427 247427 247427
774179 774179 774179
593157 593157 593157
751207 751207 751207
909474 909474 909474

output:

121893813552 326183328
1045068321267 365888698
421072132347 50616771
25673190192 945664445
3000000000000 142411650
183660360987 574138609
1798059372123 574598131
1055505679947 62300093
1692935870547 866008617
2481428870028 843792102

result:

ok 10 lines

Test #20:

score: 0
Dangerous Syscalls

input:

10
599472 268253 682858
666172 689269 998823
625414 945281 370178
798580 246142 590665
32873 131908 130577
586779 319509 393463
725788 859892 283263
609870 959975 546223
852317 667850 648721
95783 486430 365205

output:


result: