QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#99518#6325. Peaceful ResultsSorting#TL 329ms68912kbC++3.9kb2023-04-22 20:21:222023-04-22 20:21:25

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-22 20:21:25]
  • 评测
  • 测评结果:TL
  • 用时:329ms
  • 内存:68912kb
  • [2023-04-22 20:21:22]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
const ll mod=998244353;
typedef vector<ll> poly;
const int mb=20;//can change !!!!
ll roots[1<<mb];
int rev[1<<mb];
ll pw(ll x,ll y){
	if(y==0) return 1;
	if(y%2) return x*pw(x,y-1)%mod;
	ll res=pw(x,y/2);
	return res*res%mod;
}
void operator<<(ostream& out,poly y){
	for(auto c:y) out << c << ' ';
}
poly operator+(poly x,poly y){
	int n=max(x.size(),y.size());
	x.resize(n);y.resize(n);
	for(int i=0; i<n ;i++){
		x[i]+=y[i];
		if(x[i]>=mod) x[i]-=mod;
	}
	return x;
}
poly operator-(poly x,poly y){
	int n=max(x.size(),y.size());
	x.resize(n);y.resize(n);
	for(int i=0; i<n ;i++){
		x[i]+=mod-y[i];
		if(x[i]>=mod) x[i]-=mod;
	}
	return x;
}

void pre(){
	roots[0]=1;
	roots[1]=pw(15311432,1<<(23-mb));
	for(int i=1; i<(1<<mb) ;i++) roots[i]=roots[i-1]*roots[1]%mod;
}
void fft(poly &p){
	int n=p.size();
	roots[0]=1;
	int m=(1<<mb)/n;
	for(int i=1; i<n ;i++){
		rev[i]=rev[i/2]/2+((i&1)*n/2);
		if(i<rev[i]) swap(p[i],p[rev[i]]);
	}
	for(int k=1; k<n ;k*=2){
        for(int i=0; i<n ;i+=2*k){
            int cur=0,step=n/(2*k);
            for(int j=0; j<k;j++,cur+=step){
                ll x=p[i+j];
                ll y=p[i+j+k]*roots[cur*m]%mod;
                p[i+j]=(x+y>=mod?x+y-mod:x+y);
				p[i+j+k]=(x>=y?x-y:x+mod-y);
            }
        }
    }
}
poly operator*(poly x,poly y){
	int n=1;
	while(n<x.size()+y.size()-1) n*=2;
	x.resize(n,0);y.resize(n,0);
	fft(x);fft(y);
	for(int i=0; i<n ;i++) x[i]=x[i]*y[i]%mod;
	reverse(x.begin()+1,x.end());
	fft(x);
	ll inv=pw(n,mod-2);
	for(int i=0; i<n ;i++) x[i]=x[i]*inv%mod;
	while(x.size()>1 && x.back()==0) x.pop_back();
	return x;
}/*
vector<ll>multiply2(vector<ll>x,vector<ll>y){
	vector<ll>z;z.resize(x.size()+y.size()-1);
	for(auto c:z) c=0;
	for(int i=0; i<x.size() ;i++){
		for(int j=0; j<y.size() ;j++){
			z[i+j]=(z[i+j]+x[i]*y[j])%mod;	
		}
	}
	return z;
}*/
poly inverse(poly x){
	int n=1;
	poly g;g.resize(1);
	if(x[0]==1) g[0]=1;//:))
	else g[0]=pw(x[0],mod-2);
	while(n<x.size()){
		poly f0(n),g0(n),f1(n);
		if(x.size()<2*n) x.resize(2*n);
		for(int i=0; i<n ;i++){
			f0[i]=x[i];f1[i]=x[i+n];
			g0[i]=g[i];
		}
		auto tmp=poly{1}-(f0*g0);tmp.resize(2*n);
		for(int i=0; i<n ;i++) tmp[i]=tmp[i+n];
		tmp=tmp-(f1*g0);
		tmp.resize(n);
		tmp=tmp*g0;tmp.resize(n);
		g.resize(2*n);
		for(int i=0; i<n ;i++) g[i+n]=tmp[i];
		n*=2;
	}
	return g;
}
poly one = {1};
poly pw(poly x,ll y){
	if(y==0) return one;
	if(y%2) return x*pw(x,y-1);
	poly res=pw(x,y/2);
	return res*res;
}
//my code starts here
int n,m;
ll f[1500001],inf[1500001];
ll C(ll x,ll y){
	return f[x]*inf[x-y]%mod*inf[y]%mod;
}
ll a[3][3];
ll b[3][3];
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	pre();
	cin >> n;
	for(int i=0; i<3 ;i++){
		for(int j=0; j<3 ;j++){
			cin >> a[i][j];
		}
	}
	m=n;
	f[0]=1;
	for(int i=1; i<=n ;i++) f[i]=i*f[i-1]%mod;
	inf[n]=pw(f[n],mod-2);
	for(int i=n; i>=1 ;i--) inf[i-1]=i*inf[i]%mod;
	for(int i=0; i<3 ;i++){
		ll mn=n;
		for(int j=0; j<3 ;j++){
			ll cur=0;
			for(int k=0; k<3 ;k++){
				cur+=a[k][(j+k*i)%3];
			}
			mn=min(mn,cur);
		}
		for(int j=0; j<3 ;j++){
			//cout << j << endl;
			ll cur=0;
			for(int k=0; k<3 ;k++){
				cur+=a[k][(j+k*i)%3];
			}
			//cout << i << ' ' << j << ' ' << mn << ' ' << cur << endl;
			if((cur-mn)%3!=0) return cout << "0\n",0;
			ll ban=(cur-mn)/3;
			b[i][j]=ban;m-=ban;
			for(int k=0; k<3 ;k++){
				a[k][(j+k*i)%3]-=ban;
			}
		}
	}
	//cout << m << endl;
	m/=3;
	poly p[3];
	for(int i=0; i<3 ;i++){
		p[i].resize(m+1);
		for(int j=0; j<=m ;j++){
			p[i][j]=1;
			for(int k=0; k<3 ;k++){
				p[i][j]=p[i][j]*inf[j+b[i][k]]%mod;
			}
		}
	}
	auto c=p[0]*p[1];
	ll ans=0;
	for(int i=0; i<=m ;i++) ans=(ans+c[i]*p[2][m-i])%mod;
	ans=ans*f[n]%mod;
	cout << ans << '\n';
}

详细

Test #1:

score: 100
Accepted
time: 4ms
memory: 17284kb

input:

2
2 0 0
1 1 0
1 0 1

output:

2

result:

ok 1 number(s): "2"

Test #2:

score: 0
Accepted
time: 5ms
memory: 15656kb

input:

3
0 1 2
3 0 0
1 1 1

output:

0

result:

ok 1 number(s): "0"

Test #3:

score: 0
Accepted
time: 83ms
memory: 27572kb

input:

333333
111111 111111 111111
111111 111111 111111
111111 111111 111111

output:

383902959

result:

ok 1 number(s): "383902959"

Test #4:

score: 0
Accepted
time: 329ms
memory: 68828kb

input:

1500000
500000 500000 500000
500000 500000 500000
500000 500000 500000

output:

355543262

result:

ok 1 number(s): "355543262"

Test #5:

score: 0
Accepted
time: 320ms
memory: 68912kb

input:

1499999
499999 499999 500001
499999 499999 500001
499999 499999 500001

output:

934301164

result:

ok 1 number(s): "934301164"

Test #6:

score: 0
Accepted
time: 16ms
memory: 37084kb

input:

1500000
1 0 1499999
1499999 1 0
0 1499999 1

output:

1500000

result:

ok 1 number(s): "1500000"

Test #7:

score: 0
Accepted
time: 22ms
memory: 37148kb

input:

1499999
0 749999 750000
750000 0 749999
749999 750000 0

output:

713966599

result:

ok 1 number(s): "713966599"

Test #8:

score: 0
Accepted
time: 0ms
memory: 17368kb

input:

1
1 0 0
0 0 1
0 1 0

output:

1

result:

ok 1 number(s): "1"

Test #9:

score: 0
Accepted
time: 6ms
memory: 16308kb

input:

1
0 1 0
0 1 0
0 1 0

output:

1

result:

ok 1 number(s): "1"

Test #10:

score: 0
Accepted
time: 9ms
memory: 16168kb

input:

1
0 0 1
1 0 0
1 0 0

output:

0

result:

ok 1 number(s): "0"

Test #11:

score: 0
Accepted
time: 318ms
memory: 68856kb

input:

1499999
500000 500000 499999
499999 499999 500001
499999 499999 500001

output:

617065435

result:

ok 1 number(s): "617065435"

Test #12:

score: -100
Time Limit Exceeded

input:

2
1 1 0
0 0 2
0 0 2

output:


result: