QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#209884#6325. Peaceful ResultskkioRE 94ms54616kbC++179.3kb2023-10-10 18:47:242023-10-10 18:47:25

Judging History

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

  • [2023-10-10 18:47:25]
  • 评测
  • 测评结果:RE
  • 用时:94ms
  • 内存:54616kb
  • [2023-10-10 18:47:24]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
namespace ZPoly
{

using LL=long long;
constexpr int MOD=998244353,G=114514,MAXN=1<<21;
inline int qpow(LL a,LL b) { int r=1;for(;b;(b&1)?r=r*a%MOD:0,a=a*a%MOD,b>>=1);return r; }
inline int madd(int x) { return x; }
inline int mmul(int x) { return x; }
inline int msub(int x,int y) { return (x-=y)<0?x+=MOD:x; }
inline int mdiv(int x,int y) { return (LL)x*qpow(y,MOD-2)%MOD; }
template<typename ...Args>inline int madd(int x,Args ...y) { return (x+=madd(y...))>=MOD?x-=MOD:x; }
template<typename ...Args>inline int mmul(int x,Args ...y) { return (LL)x*mmul(y...)%MOD; }

class Polynomial
{
 private:
	static constexpr int NTT_LIM=180;
	static int g[MAXN+5],c1[MAXN+5],c2[MAXN+5];
	int deg;
	vector<int> c;
 public:
	static void init()
	{
		for(int i=2,gn;i<=MAXN;i<<=1)
		{
			g[i>>1]=1,gn=qpow(G,(MOD-1)/i);
			for(int j=(i>>1)+1;j<i;j++) g[j]=mmul(g[j-1],gn);
		}
	}
	static void DIT(int *a,int len)
	{
		for(int i=len>>1;i;i>>=1)
			for(int j=0;j<len;j+=i<<1)
				for(int k=0,x,y;k<i;k++)
					x=a[j+k],y=a[i+j+k],a[j+k]=madd(x,y),a[i+j+k]=mmul(g[i+k],msub(x,y));
	}
	static void DIF(int *a,int len)
	{
		for(int i=1;i<len;i<<=1)
			for(int j=0;j<len;j+=i<<1)
				for(int k=0,x,y;k<i;k++)
					x=a[j+k],y=mmul(g[i+k],a[i+j+k]),a[j+k]=madd(x,y),a[i+j+k]=msub(x,y);
		int x=qpow(len,MOD-2);
		for(int i=0;i<len;i++) a[i]=mmul(a[i],x);
		reverse(a+1,a+len);
	}
 private:
	static void __polyinv(const int *a,int *b,int len)
	{
		if(len==1) return b[0]=qpow(a[0],MOD-2),void();
		__polyinv(a,b,(len+1)>>1);
		int nn=1<<(__lg((len<<1)-1)+1);
		memcpy(c1,a,len<<2);
		memset(b+len,0,(nn-len)<<2);
		memset(c1+len,0,(nn-len)<<2);
		DIT(b,nn),DIT(c1,nn);
		for(int i=0;i<nn;i++) b[i]=mmul(b[i],msub(2,mmul(b[i],c1[i])));
		DIF(b,nn),memset(b+len,0,(nn-len)<<2);
	}
	static void __polyln(const int *a,int *b,int len)
	{
		__polyinv(a,b,len);
		for(int i=1;i<len;i++) c1[i-1]=mmul(i,a[i]);
		int nn=1<<(__lg((len<<1)-1)+1);
		memset(b+len,0,(nn-len)<<2);
		memset(c1+len,0,(nn-len)<<2);
		DIT(b,nn),DIT(c1,nn);
		for(int i=0;i<nn;i++) b[i]=mmul(b[i],c1[i]);
		DIF(b,nn),memset(b+len,0,(nn-len)<<2);
		for(int i=len-1;i>0;i--) b[i]=mdiv(b[i-1],i);
		b[0]=0;
	}
	static void __polyexp(const int *a,int *b,int l,int r)
	{
		if(l==r-1) return b[l]=(l?mdiv(b[l],l):1),void();
		int len=r-l,mid=(l+r)>>1;
		__polyexp(a,b,l,mid);
		for(int i=0;i<len;i++) c1[i]=a[i];
		memcpy(c2,b+l,(mid-l)<<2);
		memset(c2+mid-l,0,(r-mid)<<2);
		if(len<=NTT_LIM) for(int i=len-1;i>=0;i--)
		{
			c1[i]=mmul(c1[i],c2[0]);
			for(int j=0;j<i;j++) c1[i]=madd(c1[i],mmul(c1[j],c2[i-j]));
		}
		else
		{
			DIT(c1,len),DIT(c2,len);
			for(int i=0;i<len;i++) c1[i]=mmul(c1[i],c2[i]);
			DIF(c1,len);
		}
		for(int i=mid;i<r;i++) b[i]=madd(b[i],c1[i-l]);
		__polyexp(a,b,mid,r);
	}
 public:
	Polynomial(): deg(1),c(1){}
	Polynomial(const Polynomial &p): deg(p.deg),c(p.c){}
	Polynomial(Polynomial &&p): deg(p.deg),c(move(p.c)){}
	explicit Polynomial(int d): deg(d),c(d){}
	explicit Polynomial(const vector<int> &v): deg(v.size()),c(v){}
	explicit Polynomial(const initializer_list<int> &l): deg(l.size()),c(l){}
	inline int &operator [](int i) { return c[i]; }
	inline int operator [](int i)const { return c[i]; }
	inline int degree()const { return deg; }
	inline void resize(int d) { c.resize(deg=d); }
	inline Polynomial &operator +=(const Polynomial &p)
	{
		if(deg<p.deg) resize(p.deg);
		for(int i=0;i<deg;i++) c[i]=madd(c[i],p[i]);
		return *this;
	}
	inline Polynomial &operator -=(const Polynomial &p)
	{
		if(deg<p.deg) resize(p.deg);
		for(int i=0;i<deg;i++) c[i]=msub(c[i],p[i]);
		return *this;
	}
	inline Polynomial &operator *=(const Polynomial &p)
	{
		int n=deg,m=p.deg;resize(n+m-1);
		if(n+m<NTT_LIM)
		{
			memcpy(c1,c.data(),n<<2);
			memset(c2,0,(n+m-1)<<2);
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++)
					c2[i+j]=madd(c2[i+j],mmul(c1[i],p[j]));
			memcpy(c.data(),c2,(n+m-1)<<2);
		}
		else
		{
			int nn=1<<(__lg(n+m-1)+1);
			memcpy(c1,c.data(),n<<2),memcpy(c2,p.c.data(),m<<2);
			memset(c1+n,0,(nn-n)<<2),memset(c2+m,0,(nn-m)<<2);
			DIT(c1,nn),DIT(c2,nn);
			for(int i=0;i<nn;i++) c1[i]=mmul(c1[i],c2[i]);
			DIF(c1,nn),memcpy(c.data(),c1,deg<<2);
		}
		return *this;
	}
	friend inline Polynomial derivative(const Polynomial &p)
	{
		Polynomial q(p.deg-1);
		for(int i=1;i<p.deg;i++) q[i-1]=mmul(p[i],i);
		return q;
	}
	friend inline Polynomial integral(const Polynomial &p)
	{
		Polynomial q(p.deg+1);
		for(int i=1;i<p.deg;i++) q[i+1]=mdiv(p[i],i+1);
		return q;
	}
	inline Polynomial inv()const
	{
		if(c[0]==0) cerr<<"[x^0]f(x)=0, f(x)^-1 doesn't exist.\n",abort();
		int nn=1<<(__lg((deg<<1)-1)+1);
		Polynomial q(nn);
		__polyinv(c.data(),q.c.data(),deg);
		return q.resize(deg),q;
	}
	friend inline Polynomial ln(const Polynomial &p)
	{
		if(p[0]!=1) cerr<<"[x^0]f(x)!=1, ln(f(x)) doesn't exist.\n",abort();
		int nn=1<<(__lg((p.deg<<1)-1)+1);
		Polynomial q(nn);
		__polyln(p.c.data(),q.c.data(),p.deg);
		return q.resize(p.deg),q;
	}
	friend inline Polynomial exp(const Polynomial &p)
	{
		if(p[0]!=0) cerr<<"[x^0]f(x)!=0, exp(f(x)) doesn't exist.\n",abort();
		static int c[MAXN];
		int nn=1<<(__lg(p.deg-1)+1);
		for(int i=0;i<p.deg;i++) c[i]=mmul(i,p[i]);
		Polynomial q(nn);
		__polyexp(c,q.c.data(),0,nn);
		return q.resize(p.deg),q;
	}
	friend inline pair<Polynomial,Polynomial> div(const Polynomial &f,const Polynomial &g)
	{
		if(f.deg<g.deg) return make_pair(Polynomial{0},f);
		int n=f.deg-1,m=g.deg-1;
		Polynomial fr(n+1),gr(m+1);
		for(int i=0;i<=n;i++) fr[i]=f[n-i];
		for(int i=0;i<=m;i++) gr[i]=g[m-i];
		fr.resize(n-m+1),gr.resize(n-m+1),fr*=gr.inv();
		fr.resize(n-m+1),reverse(fr.c.begin(),fr.c.end());
		gr=f-fr*g,gr.resize(m);
		return make_pair(fr,gr);
	}
	inline Polynomial &operator =(const Polynomial &p)
		{ return deg=p.deg,c=p.c,*this; }
	inline Polynomial &operator =(Polynomial &&p)
		{ return deg=p.deg,c=move(p.c),*this; }
	inline Polynomial &operator *=(int k)
		{ for(auto &i: c) i=mmul(i,k);return *this; }
	inline Polynomial &operator /=(const Polynomial &rhs)
		{ return (*this)*=rhs.inv(); }
	inline Polynomial &operator %=(const Polynomial &rhs)
		{ return (*this)=div(*this,rhs).second; }
	inline Polynomial operator +(const Polynomial &rhs)const
		{ return Polynomial(*this)+=rhs; }
	inline Polynomial operator -(const Polynomial &rhs)const
		{ return Polynomial(*this)-=rhs; }
	inline Polynomial operator *(const Polynomial &rhs)const
		{ return Polynomial(*this)*=rhs; }
	inline Polynomial operator /(const Polynomial &rhs)const
		{ return Polynomial(*this)/=rhs; }
	inline Polynomial operator %(const Polynomial &rhs)const
		{ return div(*this,rhs).second; }
	friend inline Polynomial operator *(const Polynomial &p,int k)
		{ return Polynomial(p)*=k; }
	friend inline Polynomial operator *(int k,const Polynomial &p)
		{ return Polynomial(p)*=k; } 
};
int Polynomial::g[]={},Polynomial::c1[]={},Polynomial::c2[]={};
}

using Poly=ZPoly::Polynomial;

const int maxn=3e6+10,mod=998244353;
int n,A[3],B[3],C[3],q;
int fac[maxn],ifac[maxn],inv[maxn];
Poly f,g;
int main()
{
    Poly::init();
    scanf("%d",&n);
    scanf("%d%d%d",&A[1],&A[2],&A[0]);
    scanf("%d%d%d",&B[1],&B[2],&B[0]);
    scanf("%d%d%d",&C[1],&C[2],&C[0]);
    fac[0]=ifac[0]=inv[1]=1;
    for(int i=2;i<=n;i++)inv[i]=1ll*inv[mod%i]*(mod-mod/i)%mod;
    for(int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mod,ifac[i]=1ll*ifac[i-1]*inv[i]%mod;
    int a[6][7]={
        {1,0,1,0,1,0,A[0]-A[1]},
        {0,1,0,1,0,1,A[0]-A[2]},
        {1,0,0,-1,-1,1,B[0]-B[1]},
        {0,1,1,-1,-1,0,B[0]-B[2]},
        {1,0,-1,1,0,-1,C[0]-C[1]},
        {0,1,-1,0,1,-1,C[0]-C[2]}
    };
    // for(int i=0;i<6;i++,putchar('\n'))
    //     for(int j=0;j<7;j++)
    //         printf("%d ",a[i][j]);
    int ans=0;
    for(int i=0;i<6;i++)
    {
        int pos=-1;
        for(int j=i;j<6;j++)
            if(a[j][i]!=0){pos=j;break;}
        if(pos==-1){puts("0");return 0;}
        swap(a[i],a[pos]);
        for(int j=i+1;j<7;j++)if(a[i][j]%a[i][i]!=0){puts("0");return 0;}else a[i][j]/=a[i][i];
        a[i][i]=1;
        for(int j=0;j<6;j++)
            if(j!=i)
            {
                int mul=a[j][i];
                for(int k=i;k<7;k++)
                    a[j][k]-=mul*a[i][k];
            }
    }
    // for(int i=0;i<6;i++,putchar('\n'))
    //     for(int j=0;j<7;j++)
    //         printf("%d ",a[i][j]);
    int zsum=n+a[0][6]+a[1][6]+a[2][6]+a[3][6]+a[4][6]+a[5][6];
    //printf("%d\n",zsum);
    if(zsum<0||zsum%3){puts("0");return 0;}
    zsum/=3;
    f.resize(zsum+1);
    g.resize(zsum+1);
    for(int i=max({0,a[0][6],a[1][6]});i<=zsum;i++)
        f[i]=1ll*ifac[i]*ifac[i-a[0][6]]%mod*ifac[i-a[1][6]]%mod;
    for(int i=max({0,a[2][6],a[3][6]});i<=zsum;i++)
        g[i]=1ll*ifac[i]*ifac[i-a[2][6]]%mod*ifac[i-a[3][6]]%mod;
    //for(int i=0;i<n;i++)printf("%d ",f[i]);putchar('\n');
    //for(int i=0;i<n;i++)printf("%d ",g[i]);putchar('\n');
    f*=g;
    //for(int i=0;i<n;i++)printf("%d ",f[i]);putchar('\n');
    //printf("%d\n",min({zsum,C[0],C[1]-a[4][6],C[2]-a[5][6]}));
    for(int i=max({0,a[4][6],a[5][6]});i<=zsum;i++)
        ans=(ans+1ll*f[zsum-i]*ifac[i]%mod*ifac[i-a[4][6]]%mod*ifac[i-a[5][6]]%mod)%mod;
    ans=1ll*ans*fac[n]%mod;
    printf("%d\n",ans);
}
/*
15
1 6 8
2 6 7
7 3 5
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 12ms
memory: 20584kb

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: 11ms
memory: 19560kb

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: 30ms
memory: 25632kb

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: 88ms
memory: 54616kb

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: 94ms
memory: 52612kb

input:

1499999
499999 499999 500001
499999 499999 500001
499999 499999 500001

output:

934301164

result:

ok 1 number(s): "934301164"

Test #6:

score: -100
Runtime Error

input:

1500000
1 0 1499999
1499999 1 0
0 1499999 1

output:


result: