QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#426369#6325. Peaceful ResultsKevin5307RE 240ms36808kbC++235.1kb2024-05-31 09:11:432024-05-31 09:11:43

Judging History

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

  • [2024-05-31 09:11:43]
  • 评测
  • 测评结果:RE
  • 用时:240ms
  • 内存:36808kb
  • [2024-05-31 09:11:43]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
namespace Polynomial
{
	using ll=long long;
	using poly=vector<ll>;
	const ll mod=998244353;
	ll ksm(ll a,ll b)
	{
		ll ans=1;
		while(b)
		{
			if(b&1) ans=ans*a%mod;
			b>>=1;
			a=a*a%mod;
		}
		return ans;
	}
	inline int sz(const poly &p)
	{
		return p.size();
	}
	const poly operator +(const poly &a,const poly &b)
	{
		int p=sz(a),q=sz(b);
		int n=max(p,q);
		poly ret(n,0);
		for(int i=0;i<n;i++)
		{
			if(i<p) ret[i]+=a[i];
			if(i<q) ret[i]+=b[i];
			if(ret[i]>=mod) ret[i]-=mod;
		}
		return ret;
	}
	const poly operator -(const poly &a,const poly &b)
	{
		int p=sz(a),q=sz(b);
		int n=max(p,q);
		poly ret(n,0);
		for(int i=0;i<n;i++)
		{
			if(i<p) ret[i]+=a[i];
			if(i<q) ret[i]+=mod-b[i];
			if(ret[i]>=mod) ret[i]-=mod;
		}
		return ret;
	}
	poly operator *(poly a,poly b)
	{
		const ll g=3;
		int len=sz(a)+sz(b);
		int m=1;
		while(m<sz(a)+sz(b)) m*=2;
		a.resize(m);
		b.resize(m);
		vector<int> rev(m);
		for(int i=0;i<m;i++)
			rev[i]=(rev[i>>1]>>1)|((i&1)*(m>>1));
		for(int i=0;i<m;i++)
			if(rev[i]<i)
			{
				swap(a[i],a[rev[i]]);
				swap(b[i],b[rev[i]]);
			}
		for(int i=1;i<m;i<<=1)
		{
			ll gn=ksm(g,(mod-1)/i/2);
			for(int j=0;j<m;j+=(i<<1))
			{
				ll g0=1;
				for(int k=0;k<i;k++,g0=g0*gn%mod)
				{
					{
						ll x=a[j+k],y=g0*a[i+j+k]%mod;
						a[j+k]=(x+y)%mod;
						a[i+j+k]=(x+mod-y)%mod;
					}
					{
						ll x=b[j+k],y=g0*b[i+j+k]%mod;
						b[j+k]=(x+y)%mod;
						b[i+j+k]=(x+mod-y)%mod;
					}
				}
			}
		}
		for(int i=0;i<m;i++)
			a[i]=a[i]*b[i]%mod;
		for(int i=0;i<m;i++)
			if(rev[i]<i)
				swap(a[i],a[rev[i]]);
		for(int i=1;i<m;i<<=1)
		{
			ll gn=ksm(g,(mod-1)/i/2*(mod-2));
			for(int j=0;j<m;j+=(i<<1))
			{
				ll g0=1;
				for(int k=0;k<i;k++,g0=g0*gn%mod)
				{
					ll x=a[j+k],y=g0*a[i+j+k]%mod;
					a[j+k]=(x+y)%mod;
					a[i+j+k]=(x+mod-y)%mod;
				}
			}
		}
		ll val=ksm(m,mod-2);
		for(int i=0;i<m;i++)
			a[i]=a[i]*val%mod;
		a.resize(len-1);
		return a;
	}
	poly inv(poly p,int deg)
	{
		p.resize(deg);
		if(deg==1) return {ksm(p[0],mod-2)};
		poly w=inv(p,(deg+1)/2);
		poly g=w+w-p*w*w;
		g.resize(deg);
		return g;
	}
	poly deriv(poly p)
	{
		for(int i=0;i<sz(p);i++)
			p[i]=p[i]*i%mod;
		p.erase(p.begin());
		return p;
	}
	poly integ(poly p)
	{
		p.insert(p.begin(),0);
		for(int i=0;i<sz(p);i++)
			p[i]=p[i]*ksm(i,mod-2)%mod;
		return p;
	}
	poly ln(poly p)
	{
		return integ(deriv(p)*inv(p,sz(p)));
	}
	poly exp(poly p,int deg)
	{
		p.resize(deg);
		if(deg==1)
			return {1};
		poly g=exp(p,(deg+1)/2);
		g=g*(poly{1}-ln(g)+p);
		g.resize(deg);
		return g;
	}
	const poly operator %(poly a,poly b)
	{
		if(sz(a)<sz(b)) return a;
		int n=sz(a),m=sz(b);
		int d=n-m+1;
		poly a2=a,b2=b;
		reverse(a2.begin(),a2.end());
		reverse(b2.begin(),b2.end());
		a2.resize(d);
		b2.resize(d);
		poly q=a2*inv(b2,d);
		q.resize(d);
		reverse(q.begin(),q.end());
		q=a-b*q;
		q.resize(m-1);
		return q;
	}
	const poly operator /(poly a,poly b)
	{
		if(sz(a)<sz(b)) return a;
		int n=sz(a),m=sz(b);
		int d=n-m+1;
		poly a2=a,b2=b;
		reverse(a2.begin(),a2.end());
		reverse(b2.begin(),b2.end());
		a2.resize(d);
		b2.resize(d);
		poly q=a2*inv(b2,d);
		q.resize(d);
		reverse(q.begin(),q.end());
		return q;
	}
}
using namespace Polynomial;
ll M[9][10];
bool NoSolution;
void GaussianElimination()
{
	for(int i=0;i<7;i++)
	{
		if(!M[i][i])
			for(int j=i+1;j<9;j++)
				if(M[j][i])
				{
					for(int k=0;k<10;k++)
						swap(M[j][k],M[i][k]);
					break;
				}
		if(M[i][9]%M[i][i]) NoSolution=true;
		ll val=M[i][i];
		for(int j=0;j<10;j++)
			M[i][j]/=val;
		for(int j=0;j<9;j++)
			if(i!=j)
			{
				ll tmp=M[j][i];
				for(int k=0;k<10;k++)
					M[j][k]-=tmp*M[i][k];
			}
	}
}
ll fact[500500],rfact[500500];
inline bool check(int n,int x){return (x>=0)&&(x<=n);}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	fact[0]=1;
	for(int i=1;i<500500;i++)
		fact[i]=fact[i-1]*i%mod;
	for(int i=0;i<500500;i++)
		rfact[i]=ksm(fact[i],mod-2);
	int id,t=1;
	while(t--)
	{
		int n;
		memset(M,0,sizeof(M));
		cin>>n;
		for(int i=0;i<9;i++)
			cin>>M[i][9];
		M[0][0]=M[0][1]=M[0][2]=1;
		M[1][3]=M[1][4]=M[1][5]=1;
		M[2][6]=M[2][7]=M[2][8]=1;
		M[3][0]=M[3][3]=M[3][6]=1;
		M[4][1]=M[4][4]=M[4][7]=1;
		M[5][2]=M[5][5]=M[5][8]=1;
		M[6][0]=M[6][5]=M[6][7]=1;
		M[7][2]=M[7][4]=M[7][6]=1;
		M[8][1]=M[8][3]=M[8][8]=1;
		NoSolution=false;
		GaussianElimination();
		if(NoSolution)
		{
			cout<<"0\n";
			continue;
		}
		poly f(n+1),g(n+1);
		for(int i=0;i<=n;i++)
			if(check(n,M[2][9]+i)&&check(n,M[3][9]+i))
				f[i]=rfact[i]*rfact[M[2][9]+i]%mod*rfact[M[3][9]+i]%mod;
		for(int i=0;i<=n;i++)
			if(check(n,M[0][9]+i)&&check(n,M[4][9]+i))
				g[i]=rfact[i]*rfact[M[0][9]+i]%mod*rfact[M[4][9]+i]%mod;
		poly h=f*g;
		ll ans=0;
		assert(sz(h)==n+n+1);
		for(int i=0;i<=n+n;i++)
			if(check(n,M[1][9]-i)&&check(n,M[5][9]-i)&&check(n,M[6][9]-i))
				ans=(ans+h[i]*rfact[M[1][9]-i]%mod*rfact[M[5][9]-i]%mod*rfact[M[6][9]-i])%mod;
		cout<<ans*fact[n]%mod<<'\n';
	}
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 59ms
memory: 11472kb

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: 55ms
memory: 11708kb

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: 240ms
memory: 36808kb

input:

333333
111111 111111 111111
111111 111111 111111
111111 111111 111111

output:

383902959

result:

ok 1 number(s): "383902959"

Test #4:

score: -100
Runtime Error

input:

1500000
500000 500000 500000
500000 500000 500000
500000 500000 500000

output:


result: