QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#99518 | #6325. Peaceful Results | Sorting# | TL | 329ms | 68912kb | C++ | 3.9kb | 2023-04-22 20:21:22 | 2023-04-22 20:21:25 |
Judging History
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';
}
Details
Tip: Click on the bar to expand more detailed information
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