轉化一下題意:給出矩陣每行每列的最大值,求知足條件的矩陣個數。ios
先將A,B按從大到小排序,顯然沒有什麼影響。若是A的最大值不等於B的最大值那麼無解不然必定有解。ide
考慮從大到小枚舉A,B中出現的數s,那麼能夠將這個矩形分紅一些不一樣的矩形或者L形使之互不影響,且位置的值在[0,s]中,且每行每列的最大值均爲s,最後用分步乘法計數原理求解。spa
例:code
5blog
1 2 2 3 5排序
2 2 3 4 5ci
因爲矩形是特殊的L形因而咱們只考慮L形:string
設拐點的矩形爲a*b,L上部高爲c,左部長爲d。it
考慮容斥,設f[i]爲至少有i行的限制不知足條件(每列都要知足條件),io
那麼$f[i]=C_a^i * ( s^i * ( (s+1)^{a+c-i} - s^{a+c-i} ))^b * (s^i * (s+1)^{a-i} )^d$
$s^i$保證i行不知足限制,$((s+1)^{a+c-i}-s^{a+c-i})$表示剩下的至少一個知足限制條件(爲保證列知足),b次方即每列。這樣就考慮完了前b列。
那麼多出來的d列呢?大體相同。$(s^i*(s+1)^{a-i})^d$能夠發現並無保證列知足,由於L型左部上面必定比這裏大,那麼已經保證列知足限制,因此這裏就隨便選了。
$ans=\prod \sum _{i=0}^{a} -1^i*f[i]$
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #define LL long long 6 using namespace std; 7 const int mod=1e9+7; 8 struct Hash_map 9 { 10 int fi[233333],ni[233333],siz; 11 int key[233333],val[233333]; 12 inline int &operator [] (int x) 13 { 14 int k=x%233333;int i=fi[k]; 15 for(;i&&key[i]!=x;i=ni[i]); 16 if(!i)i=++siz,key[i]=x,val[i]=0,ni[i]=fi[k],fi[k]=i; 17 return val[i]; 18 } 19 }ta,tb; 20 LL poww(LL a,LL b); 21 LL jc[100010],inv[100010]; 22 LL CC(LL n,LL m){return jc[n]*inv[m]%mod*inv[n-m]%mod;} 23 int n,A[100010],B[100010],C[200010],cnt; 24 bool cmp(int a,int b){return a>b;} 25 LL f[100010]; 26 signed main() 27 { 28 // freopen("silhouette4.in","r",stdin); 29 30 jc[0]=inv[0]=1;for(int i=1;i<=100000;i++)jc[i]=jc[i-1]*i%mod,inv[i]=poww(jc[i],mod-2); 31 cin>>n; 32 for(int i=1;i<=n;i++)cin>>A[i],C[++cnt]=A[i],ta[A[i]]++; 33 for(int i=1;i<=n;i++)cin>>B[i],C[++cnt]=B[i],tb[B[i]]++; 34 sort(A+1,A+n+1,cmp);sort(B+1,B+n+1,cmp); 35 if(A[1]!=B[1]){puts("0");return 0;} 36 sort(C+1,C+cnt+1,cmp);cnt=unique(C+1,C+cnt+1)-C-1; 37 38 LL ans=1; 39 int la=1,lb=1,na=0,nb=0; 40 for(int i=1;i<=cnt;i++) 41 { 42 int s=C[i]; 43 la=na,lb=nb; 44 while(na<n&&A[na+1]==s)na++; 45 while(nb<n&&B[nb+1]==s)nb++; 46 47 int a=na-la,b=nb-lb,c=la,d=lb; 48 LL tem=0; 49 for(int j=0;j<=a;j++) 50 { 51 f[j]=CC(a,j)*poww( ( poww(s,j) * (poww(s+1,a+c-j)-poww(s,a+c-j)%mod) )%mod ,b)%mod* 52 poww( poww(s,j)*poww(s+1,a-j)%mod ,d)%mod; 53 if(j&1)tem-=f[j];else tem+=f[j]; 54 tem=(tem%mod+mod)%mod; 55 } 56 ans=(ans*tem)%mod; 57 } 58 printf("%lld\n",ans); 59 } 60 LL poww(LL a,LL b) 61 { 62 a%=mod;LL ans=1; 63 while(b) 64 { 65 if(b&1)ans=ans*a%mod; 66 a=a*a%mod;b=b>>1; 67 } 68 return ans; 69 }