D. Matrix game
链接
思路
这道题有两个知识点:组合数学+之前没解决的分数求余问题.
先说思路:注意他说的是相同的数,所以为了确保每一列至少有a个相同的数,那么\(n \ge k \times (a-1) + 1\)(指每个元素k至少出现了a-1次,然后有一个多出现了一次).
接下来考虑列:对于一列里的a个相同的元素,不难知道排列的总可能数:\(C_n^a\),那么对于k个元素:\(k \times C_n^a\),所以令\(x=k \times C_n^a\),那么列数就是\(x \times (b-1)+1\)同理.
重点:求逆对分数除法的应用:对\((\frac{a}{b}) \mod c\),有\((a \mod c) \times (invs(b) \mod c)\)所以只需要牢记invs的模版代码就行了
模版:
int qmi(int a, int b)
{
int ans = 1;
int ta = a;
while (b)
{
if (b & 1)ans = (ans*ta)%M;
ta = (ta * ta) % M;
b >>= 1;
}
return ans;
}
int invs(int a, int mod)
{
return qmi(a, mod-2) % mod;
}
代码
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define tin long long
#define itn long long
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int N = 2e5 + 10;
int t;
int a, b, k;
const int M = 1e9 + 7;
int qmi(int a, int b)
{
int ans = 1;
int ta = a;
while (b)
{
if (b & 1)ans = (ans*ta)%M;
ta = (ta * ta) % M;
b >>= 1;
}
return ans;
}
int mod_inverse(int a, int mod)
{
return qmi(a, mod-2) % mod;
}
void solve()
{
cin >> a >> b >> k;
int n = k * (a - 1) + 1;
n %= M;
int x = k;
for (int i = 1; i <= a; i++)x = (x * (n - i + 1) % M * mod_inverse(i, M)) % M;
int m = x * (b - 1) + 1;
m %= M;
n %= M;
cout << n << ' ' << m << '\n';
}
signed main() {
IOS;
cin >> t;
while(t--)
solve();
return 0;
}