QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#471084 | #21608. 行列式 | EXODUS# | RE | 0ms | 0kb | C++17 | 10.0kb | 2024-07-10 17:46:34 | 2024-07-10 17:46:34 |
answer
#include <vector>
#include <cassert>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include<cassert>
#include<vector>
namespace exodus{
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
template<typename T,typename U>
T qpow(T x,U n,int m){
if(m==1)return 0;
uint mod=uint(m);
ull res=1,y=x%mod;
for(;n;n>>=1,y=(ll)y*y%mod)
if(n&1)res=(ll)res*y%mod;
return res;
}
template<uint m,typename T,typename U>
T qpow(T x,U n){
if(m==1)return 0;
uint mod=uint(m);
ull res=1,y=x%mod;
for(;n;n>>=1,y=(ll)y*y%mod)
if(n&1)res=(ll)res*y%mod;
return res;
}
template<typename T>
T exgcd(T a,T b,T &x,T &y){
if(!b)return x=1,y=0,a;
T d=exgcd(b,a%b,y,x);y-=a/b*x;
return d;
}
bool is_prime(int n){
if(n<=1)return false;
if(n==2||n==7||n==61)return true;
if(n%2==0)return false;
ll d=n-1;
while(d%2==0)d/=2;
constexpr ll bases[3]={2,7,61};
for(ll a:bases){
ll t=d,y=qpow(a,t,n);
while(t!=n-1&&y!=1&&y!=n-1)
y=y*y%n,t<<=1;
if(y!=n-1&&t%2==0)
return false;
}
return true;
}
template<typename T>
std::vector<std::pair<T,int>>factorize(T n){
std::vector<std::pair<T,int>> v;
std::vector<std::pair<T,int>> check=[&](int i){
if(n%i==0){
v.emplace_back(i,0);
int cnt=0;
for(;n%i==0;++cnt,n/=i);
}
};
check(2);
check(3);
for(int i=5;T(i)*i<=n;i+=6){
check(i);
check(i+2);
}
if(n>1){
v.emplace_back(n,1);
}
return v;
}
template<uint mod>
struct factorization_list{
public:
factorization_list():fac(1,1){}
void expand(int p){
int pre=fac.size();
if(pre>p)return;
fac.resize(p+1);
for(int i=pre;i<=p;i++){
fac[i]=(ll)fac[i-1]*i%mod;
}
}
int operator [](int x){
assert(x>=0);
expand(x);
return fac[x];
}
private:
std::vector<int>fac;
};
template<uint mod>
struct inverse_list{
public:
inverse_list():inv(2,1){}
void expand(int p){
int pre=inv.size();
if(pre>p)return;
inv.resize(p+1);
for(int i=pre;i<=p;i++)
inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
}
int operator [](int x){
assert(x>=0);
expand(x);
return inv[x];
}
private:
std::vector<int>inv;
};
template<uint mod>
struct inverse_factorization_list{
public:
inverse_factorization_list():inv(),ifac(2,1){}
void expand(int p){
int pre=ifac.size();
if(pre>p)return;
inv.expand(p);
ifac.resize(p+1);
for(int i=pre;i<=p;i++){
ifac[i]=(ll)ifac[i-1]*inv[i]%mod;
}
}
int operator [](int x){
assert(x>=0);
expand(x);
return ifac[x];
}
private:
inverse_list<mod>inv;
std::vector<int>ifac;
};
template<uint mod>
struct binom_list{
public:
void expand(int x){
fac.expand(x);
ifac.expand(x);
}
int operator()(int x,int y){
if(x<0||y<0||x<y)return 0;
expand(x);
return (ll)fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}
private:
factorization_list<mod>fac;
inverse_factorization_list<mod>ifac;
};
}
namespace exodus{
namespace internal{
static constexpr int unroll_step=8;
template<int R, int L = 0, int M = (L + R) / 2, class F>__attribute__((always_inline))
inline void unroll(int i, F lambda) { if (R - L == 1)lambda(i + L); else unroll<M, L>(i, lambda), unroll<R, M>(i, lambda); }
}
}
namespace exodus{
typedef unsigned long long ull;
template<typename T>
struct base_matrix{
public:
base_matrix(){}
explicit base_matrix(int _deg):deg(_deg){mat.resize(deg,std::vector<T>(deg,T()));}
std::vector<T> &operator [](int p){return mat[p];}
const std::vector<T> &operator [](int p)const{return mat[p];}
int get_deg()const{return deg;}
void set_deg(int _deg){
deg=_deg;
mat.resize(deg);
for(auto &cur:mat)
cur.resize(deg),std::fill(cur.begin(),cur.end(),T());
}
bool operator ==(const base_matrix &rhs){
if(get_deg()!=rhs.get_deg())
return false;
for(int i=0;i<get_deg();i++)
for(int j=0;j<get_deg();j++)
if((*this)[i][j]!=rhs[i][j])
return false;
return true;
}
bool operator !=(const base_matrix &rhs){
return !((*this)==rhs);
}
private:
int deg;
std::vector<std::vector<T>>mat;
};
template<unsigned int mod>
struct mod_matrix:public base_matrix<int>{
public:
mod_matrix(){}
explicit mod_matrix(int _deg):base_matrix<int>(_deg){}
friend mod_matrix operator +(const mod_matrix &lhs,const mod_matrix &rhs){
assert(lhs.get_deg()==rhs.get_deg());
int deg=lhs.get_deg();
mod_matrix res(deg);
auto add=[&](int &x,int y){x+=y-mod,x+=x>>31&mod;};
for(int i=0;i<deg;i++){
int j=0;
for(;j+internal::unroll_step-1<deg;j+=internal::unroll_step)
internal::unroll<internal::unroll_step>(j,[&](int cj){add(res[i][cj]=lhs[i][cj],rhs[i][cj]);});
while(j<deg)
add(res[i][j]=lhs[i][j],rhs[i][j]),++j;
}
return res;
}
friend mod_matrix operator *(const mod_matrix &lhs,const mod_matrix &rhs){
const ull lim=16e18;
assert(lhs.get_deg()==rhs.get_deg());
int deg=lhs.get_deg();
base_matrix<ull>tmp(deg);
for(int i=0;i<deg;i++)
for(int k=0;k<deg;k++){
int j=0;
for(;j+internal::unroll_step-1<deg;j+=internal::unroll_step)
internal::unroll<internal::unroll_step>(j,[&](int cj){tmp[i][cj]+=(ull)lhs[i][k]*rhs[k][cj];if(tmp[i][cj]>lim)tmp[i][cj]%=mod;});
while(j<deg){
tmp[i][j]+=(ull)lhs[i][k]*rhs[k][j];
if(tmp[i][j]>lim)tmp[i][j]%=mod;
++j;
}
}
mod_matrix res(deg);
for(int i=0;i<deg;i++)
for(int j=0;j<deg;j++)
res[i][j]=tmp[i][j]%mod;
return res;
}
friend mod_matrix &operator +=(mod_matrix &lhs,const mod_matrix &rhs){
lhs=lhs+rhs;
return lhs;
}
friend mod_matrix &operator *=(mod_matrix &lhs,const mod_matrix &rhs){
lhs=lhs*rhs;
return lhs;
}
int det(){
int res=1;
int cnt=0;
int curdeg=this->get_deg();
std::vector<std::vector<int>>_mat(curdeg,std::vector<int>(curdeg));
for(int i=0;i<curdeg;i++)
for(int j=0;j<curdeg;j++)
_mat[i][j]=(*this)[i][j];
for(int i=0;i<curdeg;i++){
if(_mat[i][i]==0){
for(int j=i+1;j<curdeg;j++){
if(_mat[j][i]!=0)
swap(_mat[i],_mat[j]);
cnt++;
}
}
for(int j=i+1;j<curdeg;j++){
int tmp=(mod-(ull)_mat[j][i]*qpow<mod>(_mat[i][i],mod-2)%mod)%mod;
for(int k=0;k<curdeg;k++)
_mat[j][k]=((ull)_mat[i][k]*tmp+_mat[j][k])%mod;
}
}
for(int i=0;i<curdeg;i++)
res=(ull)res*_mat[i][i]%mod;
if(cnt&1)
res=(mod-res)%mod;
return res;
}
friend std::ostream &operator <<(std::ostream &os,const mod_matrix &mat){
int curdeg=mat->get_deg();
for(int i=0;i<curdeg;i++){
for(int j=0;j<curdeg;j++)
os<<mat[i][j]<<' ';
os<<'\n';
}
return os;
}
};
template<typename T>
struct base_vector{
public:
base_vector(){}
explicit base_vector(int _deg,bool _tp):deg(_deg),tp(_tp){vec.resize(deg,T());}
T &operator [](int p){return vec[p];}
const T &operator [](int p)const{return vec[p];}
int get_deg()const{return deg;}
bool get_tp()const{return tp;}
void set_deg(int _deg){
deg=_deg;
vec.resize(deg);
fill(vec.begin(),vec.end(),T());
}
private:
int deg;
bool tp;
std::vector<T>vec;
};
template<unsigned int mod>
struct mod_vector:public base_vector<int>{
public:
mod_vector(){}
explicit mod_vector(int _deg,bool _tp):base_vector<int>(_deg,_tp){}
friend mod_vector operator +(const mod_vector &lhs,const mod_vector &rhs){
assert(lhs.get_deg()==rhs.get_deg()&&lhs.get_tp()==rhs.get_tp());
int deg=lhs.get_deg(),tp=lhs.get_tp();
mod_vector res(deg,tp);
auto add=[&](int &x,int y){x+=y-mod,x+=x>>31&mod;};
int i=0;
for(;i+internal::unroll_step-1<deg;i+=internal::unroll_step)
internal::unroll<internal::unroll_step>(i,[&](int ci){add(res[ci]=lhs[ci],rhs[ci]);});
while(i<deg)
add(res[i]=lhs[i],rhs[i]),++i;
return res;
}
friend mod_vector operator *(const mod_vector &lhs,const mod_matrix<mod> &rhs){
if(lhs.get_tp()==0){
const ull lim=16e18;
assert(lhs.get_deg()==rhs.get_deg());
int deg=lhs.get_deg();
bool tp=lhs.get_tp();
base_vector<ull>tmp(deg,tp);
for(int k=0;k<deg;k++){
int j=0;
for(;j+internal::unroll_step-1<deg;j+=internal::unroll_step)
internal::unroll<internal::unroll_step>(j,[&](int cj){tmp[cj]+=(ull)lhs[k]*rhs[k][cj];if(tmp[cj]>lim)tmp[cj]%=mod;});
while(j<deg){
tmp[j]+=(ull)lhs[k]*rhs[k][j];
if(tmp[j]>lim)tmp[j]%=mod;
++j;
}
}
mod_vector res(deg,tp);
for(int j=0;j<deg;j++)
res[j]=tmp[j]%mod;
return res;
}else if(lhs.get_tp()==1){
const ull lim=16e18;
assert(lhs.get_deg()==rhs.get_deg());
int deg=lhs.get_deg();
bool tp=lhs.get_tp();
base_vector<ull>tmp(deg,tp);
for(int k=0;k<deg;k++){
int j=0;
for(;j+internal::unroll_step-1<deg;j+=internal::unroll_step)
internal::unroll<internal::unroll_step>(j,[&](int cj){tmp[cj]+=(ull)lhs[k]*rhs[cj][k];if(tmp[cj]>lim)tmp[cj]%=mod;});
while(j<deg){
tmp[j]+=(ull)lhs[k]*rhs[j][k];
if(tmp[j]>lim)tmp[j]%=mod;
++j;
}
}
mod_vector res(deg,tp);
for(int j=0;j<deg;j++)
res[j]=tmp[j]%mod;
return res;
}
}
friend mod_vector &operator +=(mod_vector &lhs,const mod_vector &rhs){
lhs=lhs+rhs;
return lhs;
}
friend mod_vector &operator *=(mod_vector &lhs,const mod_matrix<mod> &rhs){
lhs=lhs*rhs;
return lhs;
}
friend std::ostream &operator <<(std::ostream &os,const mod_vector &vec){
int curdeg=vec.get_deg();
for(int i=0;i<curdeg;i++)
os<<vec[i]<<' ';
os<<'\n';
return os;
}
};
}
#include <bits/stdc++.h>
using namespace std;
int main(){
cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin>>n;
exodus::mod_matrix<998244353> mat(n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>mat[i][j];
auto res=mat.det();
assert(res!=0);
cout<<res<<'\n';
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
494 507979999 844753235 308697058 577366689 725069158 935333779 504374900 25818576 590205152 640101368 622693010 938297920 872742027 301114974 734834637 556531110 842083217 975440662 921805913 100862321 393656903 213191224 795146059 30475198 812681603 711143306 28681751 642978178 605226383 94538558 ...