JZOJ 5384. 【NOIP2017提高A组模拟9.23】四维世界
Description
眾所周知,我們常感受的世界是三維的。
Polycarp突然對四維空間產生了興趣,他想對四維空間進行一些研究。但是在此之前,他必須先對三維世界了解透徹。
于是Polycarp決定從零維,也就是一個點,開始他的研究。我們把一個點放在三維空間中,Polycarp把這個點視為原點,并確定了三個正方向。他可以把這個點往三個方向之一拉伸一個單位,那么這個點就變為了一維的一條長度為一的線段。然后如果他把這條線段往另一方向拉伸一個單位,那么這條線就變為了二維的一個矩形。如果繼續拉伸可能就會進入三維世界,也就是變為直四棱柱。
Polycarp認為矩形、線段甚至點都可以看作某一維或某幾維為豐的直四棱柱。
現在Polycarp想演示把一個點一步一步拉伸為邊長為n的正六面體的過程,但他缺失了m種形態的直四棱柱模具(Polycarp擁有其他的所有直四棱柱模具),他想知道共有多少種演示方案。
Polycarp的演示過程需要每拉伸一個單位時對應形態的直四棱柱。
因為方案數很大,所以輸出答案對10^9+7的結果。
Input
從文件poly.in中讀入數據。
第一行兩個整數n;m,分別表示直四棱柱的邊長和他缺失的模具數量。
接下來m行,第i行三個整數x; y; z,表示第i個缺失模具的長、寬、高。
Output
輸出到文件poly.out中
一個整數,即答案。
Sample Input
2 3
1 0 1
1 1 1
0 2 0
Sample Output
36
Data Constraint
Solution
先考慮 m=0 的情況,即計算 (0,0,0) 走到 (n,n,n) 的方案數。
那么顯然答案即為:Cn3n?Cn2n ,即從 3n 步中選 n 步走 X ,在從剩下 2n 步中選 n 步走 Y。
現在加入很多的障礙點,于是我們針對這些點進行遞推。
設 F[i] 表示經過第 i 個障礙點且不經過其他障礙點的方案數。
我們發現如果可以經過其他障礙點時答案就是: F[i]=(xi+yi+zi)!xi!?yi!?zi!
同理可以得出:
F[i]=(xi+yi+zi)!xi!?yi!?zi!?∑xj≤xi,yj≤yi,zj≤ziF[j]?(xi?xj+yi?yj+zi?zj)!(xi?xj)!?(yi?yj)!?(zi?zj)!于是我們再加入 (n,n,n) 這個點作為“第 m+1 障礙點”進行處理,則答案就是 F[m+1] 。
時間復雜度 O(M2) 。
Code
#include<cstdio> #include<algorithm> using namespace std; const int N=100001,M=5002,mo=1e9+7; struct data {int x,y,z; }a[M]; long long f[M],g[N*3],h[N*3]; inline int read() {int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w; } inline long long ksm(long long x,int y) {long long s=1;while(y){if(y&1) s=s*x%mo;x=x*x%mo;y>>=1;}return s; } inline bool cmp(data x,data y) {return x.x<y.x || x.x==y.x && x.y<y.y || x.x==y.x && x.y==y.y && x.z<y.z; } int main() {int n=read(),m=read();g[0]=h[0]=1;for(int i=1;i<=n*3;i++) g[i]=g[i-1]*i%mo;h[n]=ksm(g[n],mo-2);for(int i=n-1;i;i--) h[i]=h[i+1]*(i+1)%mo;if(!m) {printf("%lld",g[n*3]*ksm(ksm(g[n],3),mo-2)%mo);return 0;}for(int i=1;i<=m;i++) a[i].x=read(),a[i].y=read(),a[i].z=read();a[m].x=a[m].y=a[++m].z=n;sort(a+1,a+1+m,cmp);for(int i=1;i<=m;i++){f[i]=g[a[i].x+a[i].y+a[i].z]*h[a[i].x]%mo*h[a[i].y]%mo*h[a[i].z]%mo;for(int j=1;j<i;j++)if(a[j].x<=a[i].x && a[j].y<=a[i].y && a[j].z<=a[i].z)f[i]=(f[i]+mo-f[j]*g[a[i].x-a[j].x+a[i].y-a[j].y+a[i].z-a[j].z]%mo*h[a[i].x-a[j].x]%mo*h[a[i].y-a[j].y]%mo*h[a[i].z-a[j].z]%mo)%mo;}printf("%lld",f[m]);return 0; }總結
以上是生活随笔為你收集整理的JZOJ 5384. 【NOIP2017提高A组模拟9.23】四维世界的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 5377. 【NOIP2017
- 下一篇: JZOJ 5385. 【NOIP2017