QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#829315 | #4542. Cyber Painter | Kevin5307 | AC ✓ | 1878ms | 19784kb | C++23 | 12.0kb | 2024-12-24 09:06:45 | 2024-12-24 09:06:50 |
Judging History
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