"蔚来杯"2022牛客暑期多校训练营7
A-Floor Tiles in a Park
题目大意:
G r a m m y Grammy Grammy 正在 P i g e l a n d C i t y P a r k Pigeland\ City\ Park Pigeland City Park 享受她的假期。 她对公园里的地砖很感兴趣。通过谨慎的测试,她发现每一块地砖是一个 W × H W \times H W×H 规格的矩形格子,并且格子上面有水平或者(和)垂直的线段,并且这些线段将矩形恰好分成了 k k k 份。
现在 G r a m m y Grammy Grammy 想要知道,对于给定的 W , H , k W,H,k W,H,k 值,通过在矩形中画线,我们能够构造出多少种不同样式的矩形?
由于答案较大,因此我们需要输出答案在对 998 244 353 998\ 244\ 353 998 244 353 取模后的结果。
注意,我们认为两个地砖是不同的,当且仅当
存在一条线段,它所在的位置仅在一个地砖上出现过,而另一个地砖对应的位置没有这条线段。
题目分析:
注意到 k k k 的数据范围较小,但 W W W 和 H H H 的数据范围较大,因此我们考虑使用暴力搜索或者通过简单枚举 k k k 的几种取值,推算出划分的情况,由此观察是否有可遵循的规律(或者就直接按照推算时的计算方法模拟即可)。
当 k = 1 k = 1 k=1 时,不用画任何线,显然答案为 1 1 1 。
当
k
=
2
k = 2
k=2 时,我们 只需要画一条水平或者垂直的线即可,答案为
(
W
+
H
−
2
)
(W + H - 2)
(W+H−2) ,大致划分情形如下:
当 k = 3 k = 3 k=3 时, 我们只需要在原先 k = 2 k = 2 k=2 的基础上,在其可分割的格子上进行划分即可。在划分时,我们注意到,若将当前划分的格子旋转 90 90 90 度,相当于在 H × W H \times W H×W 的格子上进行划分,也就是说,我们进行后期设计时候,可以设计一个仅考虑在 k = 2 k = 2 k=2 时第一种情况下的划分情况的函数,在此基础上算出 k = 3 k = 3 k=3 的情况后,再将参数颠倒过来重新计算即可,大致划分情形如下:
将上述三种情况划分完成后,我们将其旋转 90 90 90 度,就能够获得 k = 2 k = 2 k=2 时第二种情况下的划分情况。参数上我们只需要将 W W W 和 H H H 的参数互换即可。答案计算参考下方代码。
当 k = 4 k = 4 k=4 时,我们同样在 k = 3 k = 3 k=3 的基础上进行划分。 k = 3 k = 3 k=3 时,第一种情况可以分化出以下 5 5 5 种情况:
第二种情况同样可以划分出以下
5
5
5 种情况:
第三种情况可以划分出
2
2
2 种情况:
注意,这里由于 k = 4 k = 4 k=4 时,存在一种特殊的情况:
这种情况在计算时,若按照我们对调参数的方法,我们会重复计算1次,因此在函数设计里,我们需要对计算出来的数量除以
2
2
2 。由于需要取模,因此我们需要乘以
2
2
2 的逆元。
以上所有的情况,以及其旋转 90 90 90 度后对应的情况,共有 22 + 2 + 1 22 + 2 + 1 22+2+1 种情况,其中有 11 + 1 11 + 1 11+1 种因为计算公式相同的缘故,计算时分别采用公式 C w − 1 2 × ( h − 1 ) C_{w - 1}^2 \times (h - 1) Cw−12×(h−1) 和 C w − 1 3 C_{w - 1}^3 Cw−13 计算即可,对于最后一种特殊情况,计算公式为 ( n − 1 ) × ( m − 1 ) (n - 1)\times(m - 1) (n−1)×(m−1) 。
当 k = 5 k = 5 k=5 时,按照以上划分特点,我们可以划分出以下情况:
由 k = 4 k = 4 k=4 时 1 1 1 ~ 5 5 5 种情况衍生出来的有 23 23 23 种情况:
由
k
=
4
k = 4
k=4 时
6
6
6 ~
10
10
10 种情况衍生出来的有
16
16
16 种情况(处理时我们可以将上面的图片水平翻转后,剔除形式相同的情况即可):
由
k
=
4
k = 4
k=4 时
11
11
11 ~
12
12
12 种情况衍生出来的有
6
6
6 种情况:
以上 45 45 45 种情况通过旋转 90 90 90 度,容易得到另外的 45 45 45 种情况。
由
k
=
4
k = 4
k=4 时最后一种情况衍生出
8
8
8 种情况:
以上
8
8
8 种情况,由于具有高度对称性,因此在旋转后仍有多种情况重复,因此在固定参数情况下,我们只计算当中的
4
4
4 种情况。
受最后一种情况启发,我们还可以有以下
6
6
6 种情况:
以上 6 6 6 种情况,由于具有高度对称性,因此在旋转后仍有多种情况重复,因此在固定参数情况下,我们只计算当中的 3 3 3 种情况。
最后还有两种特殊情况:
以上分类想想就头皮发麻。。。 k = 5 k = 5 k=5 的情况对照了牛客题解,似乎以上所画的就是全部的了。。。拉格朗日插值法见大佬们的题解吧。。
参考代码:
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
const int mod = 998244353;
typedef long long ll;
ll qmi(ll a, ll b) {
ll ans = 1 % mod;
while(b) {
if(b & 1) ans = (ans * a) % mod;
a = (ll)a * a % mod;
b >>= 1;
}
return ans;
}
ll C(ll n, ll m) {
if(n < m) return 0;
ll ans = 1;
for(int i = n - m + 1; i <= n; i ++ ) {
ans = (ans * i) % mod;
}
for(int i = m; i > 1; i -- ) {
ans = ans * qmi(i, mod - 2) % mod;
}
return ans;
}
ll cal2(ll w, ll h) {
return (w - 1) % mod;
}
ll cal3(ll w, ll h) {
ll ans = 0;
ans = (C(w - 1, 2) + (w - 1) * (h - 1) * 2) % mod;
return ans;
}
ll cal4(ll w, ll h) {
ll ans = C(w - 1, 3);
ans = (ans + C(w - 1, 2) * (h - 1) % mod * 11) % mod;
ans = (ans + (w - 1) * (h - 1) % mod * qmi(2, mod - 2)) % mod;
return ans;
}
ll cal5(ll w, ll h) {
ll ans = C(w - 1, 4);
ans = (ans + C(w - 1, 3) * (h - 1) % mod * 26) % mod;
ans = (ans + C(w - 1, 2) * (h - 1) % mod * 7) % mod;
ans = (ans + C(w - 1, 2) * C(h - 1, 2) % mod * 32) % mod;
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
ll w, h, k; cin >> w >> h >> k;
ll ans = 0;
if(k == 1) {
ans = 1;
} else if(k == 2) {
ans = (cal2(w, h) + cal2(h, w)) % mod;
} else if(k == 3) {
ans = (cal3(w, h) + cal3(h, w)) % mod;
} else if(k == 4) {
ans = (cal4(w, h) + cal4(h, w)) % mod;
} else if(k == 5) {
ans = (cal5(w, h) + cal5(h, w)) % mod;
}
cout << ans;
return 0;
}