/* 数学题0.0 最后答案:A(n,n)*A(n+1,2)*A(n+3,m)+A(n,n)*C(m,1)*A(2,2)*C(n+1,1)*A(n+2,m-1); 简单解释一下 +之前的很显然 先排男生 然后老师插空 然后女生插空 显然符合条件 但仔细一想会发现少算了一部分 就是 老师 女生 老师 的情况 在单独考虑着一种 先选夹在中间的女生(C(m,1)) 然后老师换位置 A(2,2) 然后安排这个(C(n+1,1)) 然后剩下的女生插空 注意不能把 老师 女生 老师 和其他女生看成一样的 因为这个具有特殊性 然后就是高精了 最简单的 连压位都不用 */ #include<iostream> #include<cstdio> #include<cstring> #define ll long long using namespace std; int n,m,a[1000010],b[1000010],c[1000010],ans[10000010],l1,l2,l; void get_na() { for(int i=2;i<=n;i++) { for(int j=1;j<=l1;j++) a[j]=a[j]*i; for(int j=1;j<=l1;j++) if(a[j]>=10) { a[j+1]+=a[j]/10; a[j]=a[j]%10; } while(a[l1+1]) { l1++; a[l1+1]+=a[l1]/10; a[l1]=a[l1]%10; } } } void get_nb() { for(int i=1;i<=l1;i++) b[i]=a[i]; l2=l1; } void Mul1(int x) { for(int i=1;i<=l1;i++) a[i]=a[i]*x; for(int i=1;i<=l1;i++) if(a[i]>=10) { a[i+1]+=a[i]/10; a[i]=a[i]%10; } while(a[l1+1]) { l1++; a[l1+1]+=a[l1]/10; a[l1]=a[l1]%10; } } void Mul2(int x) { for(int i=1;i<=l2;i++) b[i]=b[i]*x; for(int i=1;i<=l2;i++) if(b[i]>=10) { b[i+1]+=b[i]/10; b[i]=b[i]%10; } while(b[l2+1]) { l2++; b[l2+1]+=b[l2]/10; b[l2]=b[l2]%10; } } void Add() { l=max(l1,l2); for(int i=1;i<=l;i++) c[i]=a[i]+b[i]; for(int i=1;i<=l;i++) if(c[i]>9) { c[i+1]++;c[i]=c[i]%10; } while(c[l+1])l++; } int main() { scanf("%d%d",&n,&m); a[1]=1;l1=1; b[1]=1;l2=1; get_na(); get_nb(); Mul1(n); Mul1(n+1); for(int i=n+3;i>=n+3-m+1;i--) Mul1(i); Mul2(2*m); Mul2(n+1); for(int i=n+2;i>=n+2-m+1+1;i--) Mul2(i); Add(); for(int i=l;i>=1;i--) printf("%d",c[i]); return 0; }
时间: 2024-11-05 05:19:10