QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#829315#4542. Cyber PainterKevin5307AC ✓1878ms19784kbC++2312.0kb2024-12-24 09:06:452024-12-24 09:06:50

Judging History

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

  • [2024-12-24 09:06:50]
  • 评测
  • 测评结果:AC
  • 用时:1878ms
  • 内存:19784kb
  • [2024-12-24 09:06:45]
  • 提交

answer

//Author: Kevin
#include<bits/stdc++.h>
//#pragma GCC optimize("O2")
using namespace std;
#define ll long long
#define ull unsigned ll
#define pb emplace_back
#define mp make_pair
#define ALL(x) (x).begin(),(x).end()
#define rALL(x) (x).rbegin(),(x).rend()
#define srt(x) sort(ALL(x))
#define rev(x) reverse(ALL(x))
#define rsrt(x) sort(rALL(x))
#define sz(x) (int)(x.size())
#define inf 0x3f3f3f3f
#define pii pair<int,int>
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
#define longer __int128_t
void die(string S){puts(S.c_str());exit(0);}
namespace conv
{
	#pragma GCC optimize("O3")
	#pragma GCC target("avx2,bmi")
	#include <bits/stdc++.h>
	#include <sys/mman.h>
	#include <sys/stat.h>
	namespace __yzlf{
	using std::cin;
	using std::cout;
	using u32=unsigned;
	using i64=long long;
	using u64=unsigned long long;
	using f64=double;
	using idt=std::size_t;
	namespace IO{
	using u8=unsigned char;
	using u16=unsigned short;
	constexpr std::size_t buf_def_size=262144;
	constexpr std::size_t buf_flush_threshold=32;
	constexpr std::size_t string_copy_threshold=512;
	constexpr u64 E16=1e16,E12=1e12,E8=1e8,E4=1e4;
	struct _io_t{
		u8 t_i[1<<15];
		int t_o[10000];
		constexpr _io_t(){
			std::fill(t_i,t_i+(1<<15),u8(-1));
			for(int i=0;i<10;++i){
				for(int j=0;j<10;++j){
					t_i[0x3030+256*j+i]=j+10*i;
				}
			}
			for(int e0=(48<<0),j=0;e0<(58<<0);e0+=(1<<0)){
				for(int e1=(48<<8);e1<(58<<8);e1+=(1<<8)){
					for(int e2=(48<<16);e2<(58<<16);e2+=(1<<16)){
						for(int e3=(48<<24);e3<(58<<24);e3+=(1<<24)){
							t_o[j++]=e0^e1^e2^e3;
						}
					}
				}
			}
		}
		void get(char*s,u32 p)const{
			*((int*)s)=t_o[p];
		}
	};
	constexpr _io_t _iot={};
	struct Qinf{
		explicit Qinf(FILE*fi):f(fi){
			auto fd=fileno(f);
			fstat(fd,&Fl);
			bg=(char*)mmap(0,Fl.st_size+4,PROT_READ,MAP_PRIVATE,fd,0);
			p=bg,ed=bg+Fl.st_size;
			madvise(bg,Fl.st_size+4,MADV_SEQUENTIAL);
		}
		~Qinf(){
			munmap(bg,Fl.st_size+1);
		}
		template<std::unsigned_integral T>Qinf&operator>>(T&x){
			skip_space();
			x=*p++-'0';
			for(;;){
				T y=_iot.t_i[*reinterpret_cast<u16*>(p)];
				if(y>99){break;}
				x=x*100+y,p+=2;
			}
			if(*p>' '){
				x=x*10+(*p++&15);
			}
			return *this;
		}
		template<std::signed_integral T>Qinf&operator>>(T&x){
			skip_space();
			int sign;
			p+=(sign=(*p=='-'));
			x=*p++-'0';
			for(;;){
				u32 y=_iot.t_i[*reinterpret_cast<u16*>(p)];
				if(y>99){break;}
				x=x*100+y,p+=2;
			}
			if(*p>' '){
				x=x*10+(*p++&15);
			}
			x=(sign?-x:x);
			return *this;
		}
		std::string_view read_token(){
			skip_space();
			auto bg=p;
			while(*p>' '){++p;}
			return {bg,p};
		}
		private:
		void skip_space(){
			while(*p<=' '){
				++p;
			}	
		}
		FILE*f;
		char*bg,*ed,*p;
		struct stat Fl;
	}qin(stdin);
	struct Qoutf{
		explicit Qoutf(FILE*fi,std::size_t sz=buf_def_size):f(fi),bg(new char[sz]),ed(bg+sz-buf_flush_threshold),p(bg){}
		~Qoutf(){
			flush();
			delete[] bg;
		}
		void flush(){
			fwrite_unlocked(bg,1,p-bg,f),p=bg;
		}
		Qoutf&operator<<(u32 x){
			wt_u32(x);
			return *this;
		}
		Qoutf&operator<<(u64 x){
			wt_u64(x);
			return *this;
		}
		Qoutf&operator<<(int x){
			x<0?(*p++='-',wt_u32(-x)):wt_u32(x);
			return *this;
		}
		Qoutf&operator<<(i64 x){
			x<0?(*p++='-',wt_u64(-x)):wt_u64(x);
			return *this;
		}
		Qoutf&operator<<(char ch){
			*p++=ch;
			return *this;
		}
		Qoutf&operator<<(std::string_view s){
			if(s.size()>=string_copy_threshold){
				flush(),fwrite_unlocked(s.data(),1,s.size(),f);
			}
			else{
				if((p+s.size())>ed)[[unlikely]]{flush();}
				memcpy(p,s.data(),s.size()),p+=s.size();
			}
			return*this;
		}
		private:
		void wt_u32(u32 x){
			if(x>=E8){
				put2(x/E8),x%=E8,putb(x/E4),putb(x%E4);
			}
			else if(x>=E4) {
				put4(x/E4),putb(x%E4);
			}
			else{
				put4(x);
			}
			chk();
		}
		void wt_u64(u64 x){
			if(x>=E8){
				u64 q0=x/E8,r0=x%E8;
				if(x>=E16){
					u64 q1=q0/E8,r1=q0%E8;
					put4(q1),putb(r1/E4),putb(r1%E4);
				} 
				else if(x>=E12){
					put4(q0/E4),putb(q0%E4);
				}
				else{
					put4(q0);
				}
				putb(r0/E4),putb(r0%E4);
			}
			else{
				if(x>=E4){
					put4(x/E4),putb(x%E4);
				}
				else{
					put4(x);
				}
			}
			chk();
		}
		void putb(u32 x){
			_iot.get(p,x),p+=4;
		}
		void put4(u32 x){
			if(x>99){
				if(x>999){
					putb(x);
				}
				else{
					_iot.get(p,x*10),p+=3;
				}	
			}
			else{
				put2(x);
			}
		}
		void put2(u32 x){
			if(x>9){
				_iot.get(p,x*100),p+=2;
			}
			else{
				*p++=x+'0';
			}
		}
		void chk(){
			if(p>ed)[[unlikely]]{
				flush();
			}
		}
		FILE *f;
		char *bg,*ed,*p;
	}qout(stdout);
	}
	using IO::qin;
	using IO::qout;
	namespace __fft{
	struct cpx{
		f64 x,y;
		cpx()=default;
		cpx(f64 xx,f64 yy):x(xx),y(yy){}
		cpx operator+(cpx b)const{return {x+b.x,y+b.y};}
		cpx operator-(cpx b)const{return {x-b.x,y-b.y};}
		//mod (x^2+1)
		cpx operator*(cpx b)const{return {x*b.x-y*b.y,x*b.y+y*b.x};}
		cpx operator*(f64 b)const{return {x*b,y*b};}
		//a*conj(b)
		friend cpx mulT(cpx a,cpx b){return {a.x*b.x+a.y*b.y,a.y*b.x-a.x*b.y};}
		//(a-b)*i
		friend cpx subI(cpx a,cpx b){return {b.y-a.y,a.x-b.x};}
		//mod (x^2-1)
		friend cpx mulY(cpx a,cpx b){return {a.x*b.x+a.y*b.y,a.x*b.y+a.y*b.x};}
		cpx operator-(){return {-x,-y};}
	};
	inline cpx Wn(auto a){return cpx(std::cos(a),std::sin(a));}
	inline cpx conj(cpx x){return {x.x,-x.y};}
	struct ffter{
		std::vector<std::array<cpx,3> > wn;
		ffter():wn{}{reserve(2);}
		//reserve(n) for dif(f,4n).
		void reserve(idt n){
			idt sz=wn.size();
			if(n<=sz){return;}
			int t=std::__lg(n),t2=(t+1)>>1;
			auto z=idt(1)<<t2;
			std::vector<std::array<cpx,3> > b(z*2);
			const auto r=0.5*acosl(-1)/z,q=r/z;
			for(idt i=0,j=(z*3)>>1,p=0;i<z;p-=z-(j>>__builtin_ctzll(++i))){
				b[i]={Wn(p*r),Wn(p*r*2),Wn(p*r*3)};
				b[i|z]={Wn(p*q),Wn(p*q*2),Wn(p*q*3)};
			}
			wn.resize(n);
			for(idt i=sz;i<n;++i){
				const auto x=b[i&(z-1)],y=b[z|(i>>t2)];
				wn[i]={x[0]*y[0],x[1]*y[1],x[2]*y[2]};
			}
		}
		void dif(cpx*f,idt n){
			if((n>>2)>wn.size()){reserve(n>>2);}
			idt L=n>>1;
			if(__builtin_ctzll(n)&1){
				for(idt j=0;j<L;++j){
					const cpx x=f[j],y=f[j+L];
					f[j]=x+y,f[j+L]=x-y;
				}
				L>>=1;
			}
			L>>=1;
			for(idt l=L<<2;L;l=L,L>>=2){
				for(idt j=0;j<L;++j){
					const cpx f0=f[j],f1=f[j+L],f2=f[j+L*2],f3=f[j+L*3];
					const cpx g0=f0+f2,g1=f1+f3,g2=f0-f2,g3=subI(f1,f3);
					f[j]=g0+g1,f[j+L]=g0-g1,f[j+L*2]=g2+g3,f[j+L*3]=g2-g3;
				}
				for(idt i=l,k=1;i<n;i+=l,++k){
					const auto [r1,r2,r3]=wn[k];
					for(idt j=i;j<i+L;++j){
						const cpx f0=f[j],f1=f[j+L]*r1,f2=f[j+L*2]*r2,f3=f[j+L*3]*r3;
						const cpx g0=f0+f2,g1=f1+f3,g2=f0-f2,g3=subI(f1,f3);
						f[j]=g0+g1,f[j+L]=g0-g1,f[j+L*2]=g2+g3,f[j+L*3]=g2-g3;
					}
				}
			}
		}
		void dit(cpx*f,idt n){
			if((n>>2)>wn.size()){reserve(n>>2);}
			idt L=1;
			for(idt l=L<<2;L<(n>>1);L=l,l<<=2){
				for(idt j=0;j<L;++j){
					const cpx f0=f[j],f1=f[j+L],f2=f[j+L*2],f3=f[j+L*3];
					const cpx g0=f0+f1,g1=f0-f1,g2=f2+f3,g3=subI(f3,f2);
					f[j]=g0+g2,f[j+L]=g1+g3,f[j+L*2]=g0-g2,f[j+L*3]=g1-g3;
				}
				for(idt i=l,k=1;i<n;i+=l,++k){
					const auto [r1,r2,r3]=wn[k];
					for(idt j=i;j<i+L;++j){
						const cpx f0=f[j],f1=f[j+L],f2=f[j+L*2],f3=f[j+L*3];
						const cpx g0=f0+f1,g1=f0-f1,g2=f2+f3,g3=subI(f3,f2);
						f[j]=g0+g2,f[j+L]=mulT(g1+g3,r1),f[j+L*2]=mulT(g0-g2,r2),f[j+L*3]=mulT(g1-g3,r3);
					}
				}
			}
			if(L!=n){
				for(idt j=0;j<L;++j){
					const cpx x=f[j],y=f[j+L];
					f[j]=x+y,f[j+L]=x-y;
				}
			}
		}
	}fft;
	inline void dif(std::vector<cpx>&f){fft.dif(f.data(),f.size());}
	inline void dit(std::vector<cpx>&f){fft.dit(f.data(),f.size());}
	}//namespace __fft
	using __fft::cpx;
	using __fft::dif;
	using __fft::dit;
	struct Barrett{
		Barrett()=default;
		Barrett(u64 P):M(P),im(u64(-1)/M+1){}
		u64 operator()(u64 x)const{
			u64 y=x-u64((__uint128_t(x)*im)>>64)*M;
			return std::min(y,y+M);
		}
		u64 mod()const{return M;}
		private:
		u64 M,im;
	};
	constexpr idt bcl(idt x){
		return x<2?1:2<<std::__lg(x-1);
	}
	namespace MTT{
	void to_poi(const u32*a,idt n,std::vector<cpx>&b,idt lm){
		b.assign(lm,{});
		for(idt i=0;i<n;++i){b[i]=cpx(a[i]>>15,a[i]&32767);}
		dif(b);
	}
	void poi_dot(std::vector<cpx>&a,std::vector<cpx>&b){
		idt lm=a.size();
		f64 fx=0.5/lm;
		for(idt i=0;i<std::min<idt>(2,lm);++i){
			cpx p=a[i],r=b[i]*fx;
			a[i]=r*(2*p.x),b[i]=cpx{r.y,-r.x}*(2*p.y);
		}
		for(idt k=2,m=3;k<lm;k<<=1,m<<=1){
			for(idt i=k,j=k<<1;--j,i<m;++i){
				cpx p=a[i],q=a[j],r=b[i]*fx,s=b[j]*fx;
				a[i]=(p+conj(q))*r,b[i]=(conj(q)-p)*r;
				a[j]=(q+conj(p))*s,b[j]=(conj(p)-q)*s;
			}
		}
	}
	void un_poi(u32*a,std::vector<cpx>&b,std::vector<cpx>&c,idt l,idt r,Barrett md){
		dit(b),dit(c);
		// note:
		// without avx512f
		// slow:f64 <-> u64.
		// fast:f64 <-> i64.
		for(idt i=l;i<r;++i){
			a[i]=md((md(i64(b[i].x+0.5))<<30)+(md(i64(b[i].y+0.5)+i64(0.5-c[i].y))<<15)+md(i64(c[i].x+0.5)));
		}
	}
	std::vector<u32> conv(const std::vector<u32>&a,const std::vector<u32>&b,Barrett md){
		idt n=a.size(),m=b.size(),u=n+m-1,lm=bcl(u);
		std::vector<cpx> buf0,buf1;
		std::vector<u32> c(u);
		to_poi(a.data(),a.size(),buf0,lm),to_poi(b.data(),b.size(),buf1,lm);
		poi_dot(buf0,buf1);
		un_poi(c.data(),buf0,buf1,0,u,md);
		return c;
	}
	}//namespace MTT
	vector<ll> conv(const vector<ll> &A,const vector<ll> &B)
	{
		vector<u32> a,b;
		for(auto x:A) a.pb(x);
		for(auto x:B) b.pb(x);
		vector<ll> ret;
		a=MTT::conv(a,b,1e9+7);
		for(auto x:a) ret.pb(x);
		return ret;
	}
	}
}
const ll mod=1e9+7;
ll fact[1001000],rfact[1001000];
int a[16];
ll C(int n,int k)
{
	if(k<0||k>n) return 0;
	return fact[n]*rfact[k]%mod*rfact[n-k]%mod;
}
map<array<int,3>,ll> Mp;
vector<ll> convolution(const vector<ll> &A,const vector<ll> &B)
{
	vector<ll> res(sz(A)+sz(B)-1);
	for(int i=0;i<sz(A);i++)
		for(int j=0;j<sz(B);j++)
			res[i+j]=(res[i+j]+A[i]*B[j])%mod;
	return res;
}
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	fact[0]=rfact[0]=rfact[1]=1;
	for(int i=1;i<1001000;i++) fact[i]=fact[i-1]*i%mod;
	for(int i=2;i<1001000;i++) rfact[i]=(mod-mod/i)*rfact[mod%i]%mod;
	for(int i=1;i<1001000;i++) rfact[i]=rfact[i-1]*rfact[i]%mod;
	int t;
	cin>>t;
	while(t--)
	{
		int n,m;
		cin>>n>>m;
		for(int i=0;i<16;i++)
			cin>>a[i];
		ll ans=0;
		Mp.clear();
		for(int A=0;A<16;A++) if((A&6)==6)
		{
			ll cf=a[A];
			a[A]--;
			if(cf) for(int B=0;B<16;B++) if((B&9)==9)
			{
				ll cf2=cf*a[B]%mod;
				a[B]--;
				if(cf2) for(int C=0;C<16;C++) if((C&3)==3)
				{
					ll cf3=cf2*a[C]%mod;
					a[C]--;
					if(cf3) for(int D=0;D<16;D++) if((D&12)==12)
					{
						ll cf4=cf3*a[D]%mod;
						a[D]--;
						if(cf4)
						{
							int cnt[3]={0,0,0};
							for(int type=0;type<16;type++)
								if(type==15)
									cnt[2]+=a[type];
								else if((type&10)==10)
									cnt[0]+=a[type];
								else if((type&5)==5)
									cnt[1]+=a[type];
							Mp[{cnt[0],cnt[1],cnt[2]}]=(Mp[{cnt[0],cnt[1],cnt[2]}]+cf4)%mod;
						}
						a[D]++;
					}
					a[C]++;
				}
				a[B]++;
			}
			a[A]++;
		}
		for(auto pr:Mp)
		{
			ll cf4=pr.second;
			array<int,3> cnt=pr.first;
			for(int i=0;i<min(n,m)-1;i++)
			{
				ll cf5=cf4*(n-i-1)%mod*(m-i-1)%mod;
				ll tot=0;
				vector<ll> v1(min(i*2,cnt[0])+1),v2(min(i*2,cnt[1])+1);
				for(int x=0;x<sz(v1);x++)
					v1[x]=C(i*2,x)*rfact[cnt[0]-x]%mod;
				for(int y=0;y<sz(v2);y++)
					v2[y]=C(i*2,y)*rfact[cnt[1]-y]%mod;
				vector<ll> v3=conv::__yzlf::conv(v1,v2);
				for(int x=0;x<sz(v3);x++) if(i*4-x<=cnt[2])
					tot=(tot+rfact[cnt[2]-i*4+x]*v3[x])%mod;
				ans=(ans+tot*fact[cnt[0]]%mod*fact[cnt[1]]%mod*fact[cnt[2]]%mod*fact[n*m-i*4-4]%mod*cf5)%mod;
			}
		}
		cout<<ans*rfact[n*m]%mod<<'\n';
	}
	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 1878ms
memory: 19784kb

input:

10000
2 1
0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0
3 1
1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0
1 1
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
1 1
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
1 3
0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0
1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 3
0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0
1 2
1 ...

output:

0
0
0
0
0
0
0
0
0
0
0
0
597798962
194245930
834284364
543970328
906286314
479624062
0
0
0
466666670
604761909
0
496428575
0
0
384954093
0
942128054
0
57644305
0
407142860
0
0
0
903001318
0
0
611739135
303696306
189542485
0
38720539
0
0
0
708377124
0
0
205555557
0
0
296078035
0
380854853
0
0
0
146969...

result:

ok 10000 lines