QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#753769#9565. Birthday Giftucup-team4906#TL 0ms0kbC++203.6kb2024-11-16 13:36:242024-11-16 13:36:29

Judging History

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

  • [2024-11-16 13:36:29]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-11-16 13:36:24]
  • 提交

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

output:


result: