なるほど。
https://yukicoder.me/problems/no/2255
問題
N次正方行列と素数Pが与えられる。
行列の一部の要素は未確定である。
不確定の位置に0~(P-1)のそれぞれが入る場合の行列式の総和をPで割った余りを答えよ。
解法
未確定の要素が1つある場合、得られる行列式は0~(P-1)が1回ずつである。
よってPが3以上の場合、P*(P-1)/2はPの倍数なので、解は0確定。
以下Pが2の場合を考える。
同じ列・行に2個以上未確定の要素がある場合、それにより行列式の総和が偶数になるので解は0。
あとは未確定の要素がある行・列を除いた要素の行列式を求めればよい。
int T,N; ll A[55][55]; int R[55],C[55]; ll P; const int MAT=1002; int mat[1002][1002]; int gf2_rank(int A[MAT][MAT],int n) { /* input */ int i,j,k; FOR(i,n) { int be=i,mi=n+1; for(j=i;j<n;j++) { FOR(k,n) if(A[j][k]) break; if(k<mi) be=j,mi=k; } if(mi>=n) break; FOR(j,n) swap(A[i][j],A[be][j]); FOR(j,n) if(i!=j&&A[j][mi]) { FOR(k,n) A[j][k] ^= A[i][k]; } } return i; } void solve() { int i,j,k,l,r,x,y; string s; cin>>T; while(T--) { cin>>N>>P; ZERO(R); ZERO(C); set<int> Rs,Cs; FOR(i,N) Rs.insert(i),Cs.insert(i); FOR(y,N) FOR(x,N) { cin>>A[y][x]; if(A[y][x]==-1) { R[y]++; C[x]++; Rs.erase(y); Cs.erase(x); } } if(P>=3) { cout<<0<<endl; continue; } FOR(i,N) { if(R[i]>1||C[i]>1) break; } if(i<N) { cout<<0<<endl; continue; } vector<int> RR,CC; FORR(r,Rs) RR.push_back(r); FORR(c,Cs) CC.push_back(c); FOR(y,RR.size()) { FOR(x,CC.size()) mat[y][x]=A[RR[y]][CC[x]]; } k=gf2_rank(mat,RR.size()); if(k==RR.size()) { cout<<1<<endl; } else { cout<<0<<endl; } } }
まとめ
Pが大きいと0が自明なのに気付かなかった。