QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#753769 | #9565. Birthday Gift | ucup-team4906# | TL | 0ms | 0kb | C++20 | 3.6kb | 2024-11-16 13:36:24 | 2024-11-16 13:36:29 |
answer
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 998244353;
#define N 200010
int n, m;
int a[N];
int fac[N], inv[N];
int limit = 1, l = 0;
vector<int>r;
vector<int>A, B;
int C(int n, int m) {if (n < m || n < 0)return 0; return 1LL * fac[n] * inv[m] % mod * inv[n - m] % mod;}
int qpow(int a, int b)
{
int ans = 1;
while (b) {if (b & 1) ans = 1LL * ans * a % mod; b >>= 1; a = 1LL * a * a % mod;}
return ans;
}
void NTT(vector<int>&a, int type)
{
for (int i = 0; i < limit; i ++) if (i < r[i])swap(a[i], a[r[i]]);
for (int mid = 1; mid < limit; mid <<= 1)
{
int wn = qpow(3, (mod - 1) / (mid << 1)); if (type == -1)wn = qpow(wn, mod - 2);
for (int R = (mid << 1), j = 0; j < limit; j += R)
{
for (int k = 0, w = 1; k < mid; k ++, w = 1LL * w * wn % mod)
{
int x = a[j + k], y = 1LL * a[j + k + mid] * w % mod;
a[j + k] = (x + y) % mod; a[j + k + mid] = (x + mod - y) % mod;
}
}
}
if (type == -1)
{
int inv = qpow(limit, mod - 2);
for (int i = 0; i < limit; i ++)a[i] = 1LL * a[i] * inv % mod;
}
}
vector<int> operator *(const vector<int>a, const vector<int>b)
{
limit = 1, l = 0;
int n = a.size(), m = b.size();
while (limit <= n + m) limit <<= 1, l ++;
r.resize(limit, 0);
for (int i = 0; i < limit; i ++)r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
vector<int>A(limit, 0), B(limit, 0);
for (int i = 0; i < n; i ++)A[i] = a[i];
for (int i = 0; i < m; i ++)B[i] = b[i];
NTT(A, 1); NTT(B, 1);
for (int i = 0; i < limit; i ++)A[i] = 1LL * A[i] * B[i] % mod;
NTT(A, -1);
vector<int>c(n + m - 1);
for (int i = 0; i < n + m - 1; i ++)c[i] = A[i];
return c;
}
void sol()
{
cin >> n >> m;
for (int i = 1; i <= n * m; i ++)cin >> a[i];
fac[0] = 1;
for (int i = 1; i <= n * m; i ++)fac[i] = 1LL * fac[i - 1] * i % mod;
inv[0] = inv[1] = 1;
for (int i = 2; i <= n * m; i ++)inv[i] = 1LL * inv[mod % i] * (mod - mod / i) % mod;
for (int i = 2; i <= n * m; i ++)inv[i] = 1LL * inv[i] * inv[i - 1] % mod;
sort(a + 1, a + n * m + 1);
A.assign(n * m + 1, 0);
B.assign(n * m + 1, 0);
for (int i = 0, c = mod - 1; i <= n; i ++, c = mod - c)
{
for (int j = 0, w = mod - c; j <= m; j ++, w = mod - w)
{
if (i == 0 && j == 0)continue;
int val = w;
val = 1LL * val * C(n, i) % mod * C(m, j) % mod;
val = 1LL * val * fac[n * m - i * m - j * n + i * j] % mod;
A[i * m + j * n - i * j] = (A[i * m + j * n - i * j] + val) % mod;
}
}
for (int i = 0; i <= n * m; i ++)B[i] = inv[i];
for (int i = 0; i <= n * m; i ++) cout << A[i] << ' '; cout << endl;
for (int i = 0; i <= n * m; i ++) cout << B[i] << ' '; cout << endl;
A = A * B;
for (int i = 0; i <= n * m; i ++) cout << (mod - A[i]) % mod << ' '; cout << endl;
int ans = 1LL * fac[n * m] * a[n * m] % mod;
cout << "??:" << ans << endl;
for (int i = 1; i <= n * m; i ++)
{
A[i] = (mod - A[i]) % mod;
ans = (ans + mod - 1LL * (a[i] - a[i - 1]) * A[i] % mod * fac[i] % mod) % mod;
}
cout << ans << '\n';
}
int main()
{
ios::sync_with_stdio(false);
int T;
cin >> T;
while (T --) sol();
return 0;
}
/*
1
2 2
1 3 2 4
4
2 2
1 3 2 4
3 1
10 10 10
1 3
20 10 30
3 4
1 1 45 1 4 1 91 9 8 10
*/
詳細信息
Test #1:
score: 0
Time Limit Exceeded
input:
5 0110101 01020102 0000021111 1012121010 0100202010