QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#189638#4907. djq 学生物sigma4250 1461ms78736kbC++2316.5kb2023-09-27 18:55:542023-09-27 18:55:55

Judging History

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

  • [2023-09-27 18:55:55]
  • 评测
  • 测评结果:0
  • 用时:1461ms
  • 内存:78736kb
  • [2023-09-27 18:55:54]
  • 提交

answer

// #pragma GCC target("avx,avx2")
// #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,n) for(int i=1;i<=int(n);i++)
#define per(i,n) for(int i=int(n)-1;i>=0;i--)
#define per1(i,n) for(int i=int(n);i>0;i--)
#define all(c) c.begin(),c.end()
#define si(x) int(x.size())
#define pb push_back
#define eb emplace_back
#define fs first
#define sc second
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
template<class T,class U> bool chmax(T& x, U y){
	if(x<y){ x=y; return true; }
	return false;
}
template<class T,class U> bool chmin(T& x, U y){
	if(y<x){ x=y; return true; }
	return false;
}
template<class T> void mkuni(V<T>& v){sort(all(v));v.erase(unique(all(v)),v.end());}
template<class T> int lwb(const V<T>& v, const T& a){return lower_bound(all(v),a) - v.begin();}
template<class T>
V<T> Vec(size_t a) {
    return V<T>(a);
}
template<class T, class... Ts>
auto Vec(size_t a, Ts... ts) {
  return V<decltype(Vec<T>(ts...))>(a, Vec<T>(ts...));
}
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
void dmpr(ostream& os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ~ ";
	dmpr(os,args...);
}
#define shows(...) cerr << "LINE" << __LINE__ << " : ";dmpr(cerr,##__VA_ARGS__)
#define dump(x) cerr << "LINE" << __LINE__ << " : " << #x << " = {";  \
	for(auto v: x) cerr << v << ","; cerr << "}" << endl;
#else
#define show(x) void(0)
#define dump(x) void(0)
#define shows(...) void(0)
#endif

template<class D> D divFloor(D a, D b){
	return a / b - (((a ^ b) < 0 && a % b != 0) ? 1 : 0);
}
template<class D> D divCeil(D a, D b) {
	return a / b + (((a ^ b) > 0 && a % b != 0) ? 1 : 0);
}

template<unsigned int mod_>
struct ModInt{
	using uint = unsigned int;
	using ll = long long;
	using ull = unsigned long long;

	constexpr static uint mod = mod_;

	uint v;
	ModInt():v(0){}
	ModInt(ll _v):v(normS(_v%mod+mod)){}
	explicit operator bool() const {return v!=0;}
	static uint normS(const uint &x){return (x<mod)?x:x-mod;}		// [0 , 2*mod-1] -> [0 , mod-1]
	static ModInt make(const uint &x){ModInt m; m.v=x; return m;}
	ModInt operator+(const ModInt& b) const { return make(normS(v+b.v));}
	ModInt operator-(const ModInt& b) const { return make(normS(v+mod-b.v));}
	ModInt operator-() const { return make(normS(mod-v)); }
	ModInt operator*(const ModInt& b) const { return make((ull)v*b.v%mod);}
	ModInt operator/(const ModInt& b) const { return *this*b.inv();}
	ModInt& operator+=(const ModInt& b){ return *this=*this+b;}
	ModInt& operator-=(const ModInt& b){ return *this=*this-b;}
	ModInt& operator*=(const ModInt& b){ return *this=*this*b;}
	ModInt& operator/=(const ModInt& b){ return *this=*this/b;}
	ModInt& operator++(int){ return *this=*this+1;}
	ModInt& operator--(int){ return *this=*this-1;}
	template<class T> friend ModInt operator+(T a, const ModInt& b){ return (ModInt(a) += b);}
	template<class T> friend ModInt operator-(T a, const ModInt& b){ return (ModInt(a) -= b);}
	template<class T> friend ModInt operator*(T a, const ModInt& b){ return (ModInt(a) *= b);}
	template<class T> friend ModInt operator/(T a, const ModInt& b){ return (ModInt(a) /= b);}
	ModInt pow(ll p) const {
		if(p<0) return inv().pow(-p);
		ModInt a = 1;
		ModInt x = *this;
		while(p){
			if(p&1) a *= x;
			x *= x;
			p >>= 1;
		}
		return a;
	}
	ModInt inv() const {		// should be prime
		return pow(mod-2);
	}
	// ll extgcd(ll a,ll b,ll &x,ll &y) const{
	// 	ll p[]={a,1,0},q[]={b,0,1};
	// 	while(*q){
	// 		ll t=*p/ *q;
	// 		rep(i,3) swap(p[i]-=t*q[i],q[i]);
	// 	}
	// 	if(p[0]<0) rep(i,3) p[i]=-p[i];
	// 	x=p[1],y=p[2];
	// 	return p[0];
	// }
	// ModInt inv() const {
	// 	ll x,y;
	// 	extgcd(v,mod,x,y);
	// 	return make(normS(x+mod));
	// }

	bool operator==(const ModInt& b) const { return v==b.v;}
	bool operator!=(const ModInt& b) const { return v!=b.v;}
	bool operator<(const ModInt& b) const { return v<b.v;}
	friend istream& operator>>(istream &o,ModInt& x){
		ll tmp;
		o>>tmp;
		x=ModInt(tmp);
		return o;
	}
	friend ostream& operator<<(ostream &o,const ModInt& x){ return o<<x.v;}
};
using mint = ModInt<998244353>;
//using mint = ModInt<1000000007>;

template<class T>
struct Matrix: public vector<vector<T>>{

	Matrix(){}
	explicit Matrix(int n) : vector<vector<T>>(n,vector<T>(n)){}
	Matrix(int h,int w) : vector<vector<T>>(h,vector<T>(w)){}
	Matrix(const vector<vector<T>>& a):vector<vector<T>>(a){}

	static Matrix E(int n){
		Matrix a(n,n);
		rep(i,n) a[i][i] = 1;
		return a;
	}
	int h() const { return (*this).size(); }
	int w() const { return (*this)[0].size(); }

	Matrix operator+(const Matrix& r) const {
		assert(h() == r.h() && w() == r.w());
		int H = h(), W = w();
		Matrix z(H,W);
		rep(i,H) rep(j,W) z[i][j] = (*this)[i][j] + r[i][j];
		return z;
	}
	Matrix operator-(const Matrix& r) const {
		assert(h() == r.h() && w() == r.w());
		int H = h(), W = w();
		Matrix z(H,W);
		rep(i,H) rep(j,W) z[i][j] = (*this)[i][j] - r[i][j];
		return z;
	}
	Matrix operator*(const Matrix& r) const {
		assert(w() == r.h());
		int A = h(), B = w(), C = r.w();
		Matrix z(A,C);
		rep(i,A) rep(k,B) rep(j,C) z[i][j] += (*this)[i][k] * r[k][j];
		return z;
	}
	Matrix& operator+=(const Matrix& r){return (*this)=(*this)+r;}
	Matrix& operator-=(const Matrix& r){return (*this)=(*this)-r;}
	Matrix& operator*=(const Matrix& r){return (*this)=(*this)*r;}

	Matrix& operator*=(const T& r){
		rep(i,h()) rep(j,w()) (*this)[i][j] *= r;
		return *this;
	}
	Matrix operator*(const T& r) const {
		return Matrix(*this) *= r;
	}

	Matrix pow(ll p) const {
		assert(h() == w());
		Matrix res = E(h());
		Matrix x = *this;
		while(p){
			if(p&1) res *= x;
			x *= x;
			p >>= 1;
		}
		return res;
	}

	friend ostream& operator<<(ostream &o,const Matrix& A){
		rep(i,A.h()){
			rep(j,A.w()) o << A[i][j]<<" ";
			o << endl;
		}
		return o;
	}

	T trace(){
		T t = 0;
		rep(i,h()) t += (*this)[i][i];
		return t;
	}
};
using Mat = Matrix<mint>;

V<mint> fact,ifact,invs;
mint Choose(int a,int b){
	if(b<0 || a<b) return 0;
	return fact[a] * ifact[b] * ifact[a-b];
}
void InitFact(int N){	//[0,N]
	N++;
	fact.resize(N);
	ifact.resize(N);
	invs.resize(N);
	fact[0] = 1;
	rep1(i,N-1) fact[i] = fact[i-1] * i;
	ifact[N-1] = fact[N-1].inv();
	for(int i=N-2;i>=0;i--) ifact[i] = ifact[i+1] * (i+1);
	rep1(i,N-1) invs[i] = fact[i-1] * ifact[i];
}
template<class T>
T rnd(T l,T r){	//[l,r)
	using D = uniform_int_distribution<T>;
	static random_device rd;
	static mt19937 gen(rd());
	return D(l,r-1)(gen);
}
template<class T>
T rnd(T n){	//[0,n)
	return rnd(T(0),n);
}

/*
	inversion
	なければ {{}}
*/
template<class T>
vector<vector<T>> Matrixinv(vector<vector<T>> a){
	assert(a.size() == a[0].size());
	vector<vector<T>> no;
	int n = a.size();
	vector<int> ih(n,-1), jh(n,-1);
	rep(k,n){
		for(int i=k;i<n;i++) if(ih[k] == -1){
			for(int j=k;j<n;j++) if(a[i][j]){
				ih[k] = i, jh[k] = j; break;
			}
		}
		if(ih[k] == -1) return no;
		rep(j,n) swap(a[k][j],a[ih[k]][j]);
		rep(i,n) swap(a[i][k],a[i][jh[k]]);
		if(!a[k][k]) return no;
		a[k][k] = a[k][k].inv();
		rep(i,n) if(i != k) a[k][i] *= a[k][k];
		rep(i,n) if(i != k){
			rep(j,n) if(j != k){
				a[i][j] -= a[i][k]*a[k][j];
			}
		}
		rep(i,n) if(i != k) a[i][k] *= -a[k][k];
	}
	per(k,n){
		rep(j,n) swap(a[k][j],a[jh[k]][j]);
		rep(i,n) swap(a[i][k],a[i][ih[k]]);
	}
	return a;
}

/*
	テンソル積 (クロネッカー積)
	A⊗B =[a{0,0}B .. a_{0,w-1}B]
		  [a{1,0}B .. a_{1,w-1}B]
			:
	Aの1マスを分割してBにするイメージ
*/
template<class T>
vector<vector<T>> tensor(vector<vector<T>> A, vector<vector<T>> B){
	int ah = si(A), aw = si(A[0]), bh = si(B), bw = si(B[0]);
	vector<vector<T>> C(ah*bh,vector<T>(aw*bw));
	rep(ai,ah) rep(aj,aw){
		rep(bi,bh) rep(bj,bw){
			C[ai*bh+bi][aj*bw+bj] = A[ai][aj] * B[bi][bj];
		}
	}
	return C;
}

VV<int> perms;
VV<int> op;
V<int> inv;
VV<int> types;
V<int> type;

/*
	charTable[irred rep][cycle type]
	Sn の表現論なので irred rep の方も cycle type で indexed できるが、
	irred rep の順番は自由にしていい
	cycle type の index は type[] と一致してないといけない
	S_20 くらいまでの表を生成してくれるサイト: https://www.jgibson.id.au/articles/characters/
	https://math.mit.edu/events/stanley70/Site/Slides/Early.pdf
	この表の順番は type[] と一致してる
*/

VV<Mat> irredReps;
V<int> dims;

/*
	でかい順にならべたときの辞書順
	{{1,1,1,1,1,},{2,1,1,1,},{2,2,1,},{3,1,1,},{3,2,},{4,1,},{5,},}
*/
void enumTypes(int n){
	V<int> a;
	auto dfs = [&](auto&& self, int s, int p) -> void {
		if(s == 0){
			types.pb(a);
			return;
		}
		rep1(i,min(p,s)){
			a.pb(i);
			self(self,s-i,i);
			a.pop_back();
		}
	};
	dfs(dfs,n,n);
	// show(types);
}

void initPerms(int n){
	V<int> a(n); iota(all(a),0);
	do{
		perms.pb(a);
	}while(next_permutation(all(a)));
	int m = si(perms);
	op = VV<int>(m,V<int>(m));
	inv = V<int>(m);
	rep(i,m) rep(j,m){
		V<int> ij(n);
		rep(k,n) ij[k] = perms[i][perms[j][k]];
		op[i][j] = find(all(perms),ij) - perms.begin();
		if(op[i][j] == 0) inv[i] = j;
	}
	enumTypes(n);
	rep(i,m){
		V<int> b = perms[i];
		V<bool> done(n);
		V<int> cs;
		rep(j,n) if(!done[j]){
			int c = 0;
			int x = j;
			while(!done[x]){
				done[x] = true;
				c++;
				x = b[x];
			}
			cs.pb(c);
		}
		sort(all(cs),greater<int>());
		type.pb(lwb(types,cs));
	}
	// show(perms);show(op);show(type);
}

void initIrredReps(){
	irredReps.resize(3);	// num of irred reps
	for(auto& irred: irredReps) irred.resize(6);
	// 012 021 102 120 201 210
	using M = VV<mint>;
	rep(j,6) irredReps[0][j] = VV<mint>{{1}};
	irredReps[1] = {M{{1}},M{{-1}},M{{-1}},M{{1}},M{{1}},M{{-1}}};
	irredReps[2][0] = M{{1,0},{0,1}};
	irredReps[2][1] = M{{1,0},{1,-1}};
	irredReps[2][2] = M{{-1,1},{0,1}};
	irredReps[2][3] = M{{0,-1},{1,-1}};
	irredReps[2][4] = M{{-1,1},{-1,0}};
	irredReps[2][5] = M{{0,-1},{-1,0}};
	for(auto& irred: irredReps){
		rep(i,6) rep(j,6) assert(irred[i] * irred[j] == irred[op[i][j]]);
	}

	rep(s,si(irredReps)){
		dims.pb(irredReps[s][0].h());
	}
}

// vector<Mat> FT1(V<mint> a){
// 	vector<Mat> za;
// 	for(auto& irrep: irredReps){
// 		int k = irrep[0].h();
// 		Mat sm(k);
// 		rep(v,6) sm += irrep[v] * a[v];
// 		za.pb(sm);
// 	}
// 	return za;
// }
// V<mint> iFT1(vector<Mat> za){
// 	vector<mint> a(6);
// 	rep(v,6){
// 		rep(s,3) a[v] += dims[s] * (irredReps[s][inv[v]] * za[s]).trace();
// 	}
// 	mint coef = mint(6).inv();
// 	rep(i,6) a[i] *= coef;
// 	return a;
// }

vector<Mat> FT1(vector<Mat> a){
	vector<Mat> za;
	for(auto& irrep: irredReps){
		int k = a[0].h() * irrep[0].h();
		Mat sm(k);
		rep(v,6) sm += tensor(a[v],irrep[v]);
		za.pb(sm);
	}
	return za;
}

/*
	Mat za はテンソルなわけだが、最後に右からかけた行列がd*d で、これを一点に圧縮するイメージ
	za の各 d*d ブロックにたいして、1次元バージョンのやつをやる
*/
vector<Mat> iFT1(vector<Mat> za){
	int n = si(za[0]) / dims[0];
	vector<Mat> a(6,Mat(n));
	rep(s,3) rep(v,6){
		int d = dims[s];
		rep(i,n) rep(j,n){
			Mat block(d);
			rep(ii,d) rep(jj,d) block[ii][jj] = za[s][i*d+ii][j*d+jj];
			a[v][i][j] += dims[s] * (block * irredReps[s][inv[v]]).trace();
		}
	}
	mint coef = mint(6).inv();
	rep(i,6) a[i] *= coef;
	return a;
}


// V<mint> conv1(V<mint> a, V<mint> b){
// 	vector<Mat> za = FT1(a), zb = FT1(b);
// 	rep(s,si(za))  za[s] *= zb[s];
// 	return iFT1(za);
// }

// V<mint> conv1_brute(V<mint> a, V<mint> b){
// 	int n = si(a);
// 	V<mint> c(n);
// 	rep(i,n) rep(j,n) c[op[i][j]] += a[i]*b[j];
// 	return c;
// }


template<class T>
struct ndarray{
	int S;
	vector<T> v;
	vector<int> ms;
	vector<int> coefs;

	ndarray(){}
	ndarray(vector<int> ms_):ms(ms_),coefs(si(ms_),1){
		for(int d=si(ms)-2;d>=0;d--) coefs[d] = coefs[d+1] * ms[d+1];
		S = 1; rep(d,si(ms)) S *= ms[d];
		v.resize(S);
	}
	int id(const vector<int>& is) const {
		int s = 0;
		for(int d=0;d<si(ms);d++) s += is[d] * coefs[d];
		return s;
	}
	vector<int> di(int i){
		V<int> is(si(ms));
		rep(d,si(ms)){
			is[d] = i/coefs[d];
			i %= coefs[d];
		}
		return is;
	}

	T& operator[](const vector<int>& is){
		return v[id(is)];
	}
	const T& operator[](const vector<int>& is) const {
		return v[id(is)];
	}
	T& operator[](int i){
		return v[i];
	}
	const T& operator[](int i) const {
		return v[i];
	}

	friend ostream& operator<<(ostream &o,const ndarray& a){
		return o << a.v;
	}
	int size(){
		return S;
	}
	int dim(){
		return si(ms);
	}
};

template<class T> using arr = ndarray<T>;

arr<Mat> FT(arr<mint> a_){
	arr<Mat> a(a_.ms); rep(i,a.size()) a[i] = VV<mint>{{a_[i]}};
	int n = a.dim();
	rep(d,n){
		// d次元目を変換
		// a[3][3][0,..,5][6][6] -> a[3][3][0,..,2][6][6]
		V<int> nms = a.ms; nms[d] = 3;
		arr<Mat> na(nms);
		int S = a.size();
		int D = 1; rep(_,n-1-d) D *= 6;
		rep(s,S) if(a.di(s)[d] == 0){
			V<Mat> slice(6);
			rep(i,6) slice[i] = a[s+D*i];
			V<Mat> zslice = FT1(slice);
			V<int> is = a.di(s);
			rep(i,3){
				is[d] = i;
				na[is] = zslice[i];
			}
		}
		a = na;
	}
	return a;
}
arr<mint> iFT(arr<Mat> a){
	int n = a.dim();
	per(d,n){
		// d次元目を逆変換
		// a[3][3][0,..,5][6][6] <- a[3][3][0,..,2][6][6]
		V<int> nms = a.ms; nms[d] = 6;
		arr<Mat> na(nms);
		int S = a.size();
		int D = 1; rep(_,n-1-d) D *= 6;
		rep(s,S) if(a.di(s)[d] == 0){
			V<Mat> zslice(3);
			rep(i,3) zslice[i] = a[s+D*i];
			V<Mat> slice = iFT1(zslice);
			V<int> is = a.di(s);
			rep(i,6){
				is[d] = i;
				na[is] = slice[i];
			}
		}
		a = na;
	}
	arr<mint> res(a.ms);
	rep(i,a.size()) res[i] = a[i][0][0];
	return res;
}

arr<mint> conv(arr<mint> a, arr<mint> b){
	arr<Mat> za = FT(a), zb = FT(b);
	rep(i,za.size()) za[i] *= zb[i];
	return iFT(za);
}
arr<mint> conv_brute(arr<mint> a, arr<mint> b){
	int S = a.size();
	int n=0;
	{
		int x = S;
		while(x>1){
			x/=6;
			n++;
		}
	}
	arr<mint> c(V<int>(n,6));
	rep(i,S) rep(j,S){
		auto is = c.di(i);
		auto js = c.di(j);
		V<int> ks(si(is));
		rep(_,si(ks)) ks[_] = op[is[_]][js[_]];
		c[ks] += a[i]*b[j];
	}
	return c;
}

void TEST(){
	if(false){
		int n; cin >> n;
		V<int> ms(n,6);
		arr<mint> a(ms);
		rep(i,a.size()) a[i] = rnd(2);
		auto za = FT(a);
		auto aa = iFT(za);
		cerr << a << endl;
		cerr << za << endl;
		cerr << aa << endl;
		assert(a.v == aa.v);
		exit(0);
	}
	if(false){
		int n; cin >> n;
		V<int> ms(n,6);
		arr<mint> a(ms),b(ms);
		rep(i,a.size()) a[i] = rnd(2);
		rep(i,b.size()) b[i] = rnd(2);
		auto za = FT(a);
		auto aa = iFT(za);
		assert(a.v == aa.v);
		cerr << conv(a,b) << endl;
		cerr << conv_brute(a,b) << endl;
		exit(0);
	}

	// while(true){
	// 	V<mint> a(6),b(6);
	// 	rep(i,6) cin >> a[i];
	// 	rep(i,6) cin >> b[i];
	// 	show(conv1_brute(a,b));
	// 	show(conv1(a,b));
	// }
	// while(true){
	// 	V<mint> a(6); rep(i,6) cin >> a[i];
	// 	auto za = FT1(a);
	// 	show(za);
	// 	auto aa = iFT1(za);
	// 	show(aa);
	// }
}



int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);		//DON'T USE scanf/printf/puts !!
	cout << fixed << setprecision(20);

	initPerms(3);
	initIrredReps();
	// cerr << "OK" << endl;

	// TEST();

	int n; cin >> n;
	int S = 1; rep(_,n) S *= 6;
	// arr<mint> in(V<int>(n,6)); rep(i,S) cin >> in[i];
	arr<mint> in(V<int>(n,6)); rep(i,S) in[i] = rnd(114514);
	// ans = p/(1-(1-p)f) = inv(M-in)

	mint M = accumulate(all(in.v),mint(0)) + 1;
	arr<mint> f(V<int>(n,6)); rep(i,S) f[i] = -in[i];
	f[0] += M;
	auto zf = FT(f);
	// h = id, zh = 単位行列からなるやつら
	arr<Mat> zg(zf.ms);
	rep(i,zf.size()){
		zg[i] = Matrixinv(zf[i]);
		if(zg[i].empty()){
			cout << -1 << endl; return 0;
		}
	}
	auto g = iFT(zg);
	// cerr << g << endl;
	// cerr << accumulate(all(g.v),mint(0)) << endl;
	ll ans = 0;
	for(mint v: g.v) ans ^= v.v;
	cout << ans << endl;
}

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Wrong Answer

Test #1:

score: 0
Wrong Answer
time: 1ms
memory: 3640kb

input:

1
10 10 10 10 499122217 499122156

output:

240369097

result:

wrong answer 1st numbers differ - expected: '-1', found: '240369097'

Subtask #2:

score: 0
Skipped

Dependency #1:

0%

Subtask #3:

score: 0
Wrong Answer

Test #8:

score: 0
Wrong Answer
time: 1461ms
memory: 78736kb

input:

7
13237606 0 0 696947386 879320747 0 0 0 0 0 0 0 0 0 0 0 0 0 266959993 0 0 371358373 632390641 0 666960563 0 0 708812199 564325578 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 299649176 0...

output:

921056708

result:

wrong answer 1st numbers differ - expected: '101942575', found: '921056708'

Subtask #4:

score: 0
Skipped

Dependency #1:

0%

Subtask #5:

score: 0
Skipped

Dependency #1:

0%