QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#730672 | #9572. Bingo | ucup-team4967# | TL | 2ms | 4564kb | C++20 | 3.9kb | 2024-11-09 20:59:51 | 2024-11-09 20:59:52 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define REP(i,n) for(ll i=0;i<(n);i++)
const long long MOD = 998244353;
vector<ll> fact(200200);
ll inverse(ll x){
ll e = MOD-2;
ll b = x, r = 1;
while(e>0){
if(e%2==1){
r = (r*b)%MOD;
}
e /= 2;
b = (b*b)%MOD;
}
return r;
}
ll comb(ll n, ll r){
ll Ans = fact[n];
Ans = (Ans*inverse(fact[r]))%MOD;
Ans = (Ans*inverse(fact[n-r]))%MOD;
return Ans;
}
// N,M のグリッドに K 個置く。ただし縦横ビンゴができてはならない
ll solve2(ll N, ll M, ll K){
if(!(0<=K && K<=N*M))return 0;
ll Ans = 0;
vector<ll> d(N*M,0);
REP(i,K){d[N*M-1-i]=1;}
do{
bool c = true;
REP(i,N){
bool e = true;
REP(j,M){
if(d[i*M+j]==0)e=false;
}
if(e)c=false;
}
REP(j,M){
bool e = true;
REP(i,N){
if(d[i*M+j]==0)e=false;
}
if(e)c=false;
}
if(c)Ans++;
}while(next_permutation(d.begin(),d.end()));
Ans %= MOD;
return Ans;
}
// N,M のグリッドに K 個置く。ただし縦横ビンゴができてはならない
// ll solve2(ll N, ll M, ll K){
// ll Ans = 1;
// if(N>M)swap(N,M);
// if(K<N){
// return fact[N*M];
// }
// ll rem = N*M-K;
// REP(i,N){
// }
// }
void solve(){
ll N,M;
cin >> N >> M;
vector<ll> A(N*M+1,0);
REP(i,N*M){cin >> A[i+1];}
sort(A.begin(),A.end());
vector<ll> R(N*M+1,0);
REP(K,N*M+1){
if(K==0)continue;
ll num = 0,num2;
// タテ
num2 = solve2(N,M-1,K-N);
num += num2;
// ヨコ
num2 = solve2(N-1,M,K-M);
num += num2;
// タテヨコ
num2 = solve2(N-1,M-1,K-N-M+1);
num += num2;
num = (num * fact[K-1])%MOD;
num = (num * fact[N*M-K])%MOD;
num = (num*N*M)%MOD;
R[K] = num;
}
// cout << "NM: " << N << " " << M << endl;
// cout << "R: ";
// REP(i,N*M){cout << R[i+1] << " ";}cout << endl;
ll Ans = 0;
REP(i,N*M+1){
ll num = (R[i]%MOD)*A[i];
num %= MOD;
Ans = (Ans+num)%MOD;
}
cout << Ans << endl;
}
signed main(void){
//cin.tie(nullptr);
//ios::sync_with_stdio(false);
// for(ll N=1;N<=3;N++){
// for(ll M=1;M<=4;M++){
// vector<ll> R(N*M+1,0);
// cout << "N=" << N << ", M=" << M << endl;
// vector<ll> d(N*M,0);
// REP(i,N*M){d[i]=i;}
// do{
// ll Ans = 1ll<<61;
// REP(i,N){
// REP(j,M){
// bool e = false;
// bool c = true;
// REP(k,N){
// if(d[i*M+j] < d[k*M+j])c=false;
// }
// if(c)e=true;
// c = true;
// REP(l,M){
// if(d[i*M+j] < d[i*M+l])c=false;
// }
// if(c)e=true;
// if(e){
// Ans = min(Ans,d[i*M+j]);
// }
// }
// }
// R[Ans]++;
// }while(next_permutation(d.begin(),d.end()));
// REP(i,N*M){
// cout << R[i] << " ";
// }cout << endl << endl;
// }
// }
fact[0] = 1;
REP(i,200100){
fact[i+1] = (fact[i] * (i+1))%MOD;
}
ll T;
cin >> T;
REP(i,T){solve();}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 4564kb
input:
4 2 2 1 3 2 4 3 1 10 10 10 1 3 20 10 30 3 4 1 1 4 5 1 4 1 9 1 9 8 10
output:
56 60 60 855346687
result:
ok 4 number(s): "56 60 60 855346687"
Test #2:
score: 0
Accepted
time: 0ms
memory: 4420kb
input:
1 2 2 0 0 998244352 998244352
output:
998244345
result:
ok 1 number(s): "998244345"
Test #3:
score: -100
Time Limit Exceeded
input:
900 1 1 810487041 1 2 569006976 247513378 1 3 424212910 256484544 661426830 1 4 701056586 563296095 702740883 723333858 1 5 725786515 738465053 821758167 170452477 34260723 1 6 204184507 619884535 208921865 898995024 768400582 369477346 1 7 225635227 321139203 724076812 439129905 405005469 369864252...
output:
810487041 495026756 540662911 541929691 118309348 270925149 575366228 709974238 761347712 304011276 14811741 366145628 638305530 240546928 484276475 603344008 926633861 161768904 239961447 329781933 315752584 578075668 259941994 600147169