description
analysis
考虑\((0,0,0)\)走到某个点\((i,j,k)\)的贡献,相当于插板问题
\(i+j\)个空插\(k\)个板可以有空,\(i\)个空插\(j\)个板可以有空,就是\(C^k_{i+j+k}*C^j_{i+j}\)
对于每个障碍,要算出被它包含的障碍走到它的合法方案数少了多少
那么就是拿答案减去走到被包含的障碍的答案乘右上角矩形的贡献
code
#pragma GCC optimize("O3") #pragma G++ optimize("O3") #include<stdio.h> #include<string.h> #include<algorithm> #define MAX 300000 #define ha 1000000007 #define ll long long #define reg register ll #define fo(i,a,b) for (reg i=a;i<=b;++i) #define fd(i,a,b) for (reg i=a;i>=b;--i) using namespace std; ll fac[300005],inv[300005]; ll f[305][305][305]; bool bz[305][305][305]; ll n,m; struct node { ll x,y,z,ans; }a[5005]; inline ll read() { ll x=0,f=1;char ch=getchar(); while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();} while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar(); return x*f; } inline ll cube(ll x){return x*x%ha*x%ha;} inline ll pow(ll x,ll y) { ll z=1; while (y){if (y&1)z=z*x%ha;x=x*x%ha,y>>=1;} return z; } inline ll C(ll m,ll n){return fac[n]*inv[n-m]%ha*inv[m]%ha;} inline ll get(ll i,ll j,ll k){return C(k,i+j+k)*C(j,i+j)%ha;} inline bool cmp(node a,node b){return a.x<b.x || (a.x==b.x && a.y<b.y) || (a.x==b.x && a.y==b.y && a.z<b.z);} int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); n=read(),m=read(); if (!m) { fac[0]=1;fo(i,1,MAX)fac[i]=fac[i-1]*i%ha; printf("%lld\n",fac[3*n]*pow(cube(fac[n]),ha-2)%ha); return 0; } if (n<=300) { memset(bz,1,sizeof(bz)),f[0][0][0]=1; fo(i,1,m)bz[read()][read()][read()]=0; fo(i,0,n)fo(j,0,n)fo(k,0,n) { if (bz[i+1][j][k])(f[i+1][j][k]+=f[i][j][k])%=ha; if (bz[i][j+1][k])(f[i][j+1][k]+=f[i][j][k])%=ha; if (bz[i][j][k+1])(f[i][j][k+1]+=f[i][j][k])%=ha; } printf("%lld\n",f[n][n][n]); return 0; } fac[0]=inv[0]=1;fo(i,1,MAX)fac[i]=fac[i-1]*i%ha; inv[MAX]=pow(fac[MAX],ha-2);fd(i,MAX-1,1)inv[i]=inv[i+1]*(i+1)%ha; fo(i,1,m)a[i].x=read(),a[i].y=read(),a[i].z=read(),a[i].ans=get(a[i].x,a[i].y,a[i].z); ++m,a[m].x=n,a[m].y=n,a[m].z=n,a[m].ans=get(n,n,n),sort(a+1,a+m+1,cmp); fo(i,1,m)fo(j,1,i-1)if (a[i].x>=a[j].x && a[i].y>=a[j].y && a[i].z>=a[j].z) a[i].ans=(a[i].ans-a[j].ans*get(a[i].x-a[j].x,a[i].y-a[j].y,a[i].z-a[j].z)%ha+ha)%ha; printf("%lld\n",a[m].ans); return 0; }