[HNOI2012]排队
Description
某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检。他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的)
Input
只有一行且为用空格隔开的两个非负整数 n 和 m,其含义如上所述。
对于 30%的数据 n≤100,m≤100
对于 100%的数据 n≤2000,m≤2000
Output
输出文件 output.txt 仅包含一个非负整数,表示不同的排法个数。注意答案可能很大。
Sample Input
1 1
Sample Output
12
题解:
$$Ans=A{^n_n}×A{^2_{n+1}}×A{^m_{n+3}}+A{^n_n}×A{^1_{n+1}}×A{^2_2}×A{^1_m}×A{^{m-1}_{n+2}}$$
无脑高精度,代码瞬间一百行。。。
1 //Never forget why you start 2 #include<iostream> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<algorithm> 8 #define mod (100000000) 9 using namespace std; 10 typedef long long lol; 11 int n,m; 12 struct big_num { 13 lol f[2005]; 14 big_num() { 15 memset(f,0,sizeof(f)); 16 } 17 void clean() { 18 memset(f,0,sizeof(f)); 19 } 20 void give(lol x) { 21 lol i; 22 for(i=1; x; i++) { 23 f[i]=x%mod; 24 x/=mod; 25 } 26 f[0]=i-1; 27 } 28 friend big_num operator + (const big_num a,const big_num b) { 29 lol j=0,to=max(a.f[0],b.f[0]); 30 big_num ans; 31 for(lol i=1; i<=to; i++) { 32 ans.f[i]=a.f[i]+b.f[i]+j; 33 if(ans.f[i]>=mod) { 34 j=ans.f[i]/mod; 35 ans.f[i]%=mod; 36 if(i==to)to++; 37 } else j=0; 38 } 39 ans.f[0]=to; 40 return ans; 41 } 42 friend big_num operator * (const big_num a,const big_num b) { 43 lol k=0,to=0,end=0; 44 big_num ans; 45 for(lol i=1; i<=a.f[0]; i++) { 46 k=0; 47 to=b.f[0]; 48 for(lol j=1; j<=to; j++) { 49 ans.f[i+j-1]+=a.f[i]*b.f[j]+k; 50 end=max(end,i+j-1); 51 if(ans.f[i+j-1]>=mod) { 52 k=ans.f[i+j-1]/mod; 53 ans.f[i+j-1]%=mod; 54 if(j==to)to++; 55 } else k=0; 56 } 57 } 58 ans.f[0]=end; 59 return ans; 60 } 61 friend big_num operator / (const big_num a,const lol b) { 62 lol to=a.f[0],k=0,end=0; 63 big_num ans; 64 for(lol i=to; i>=1; i--) { 65 lol s=k*mod+a.f[i]; 66 ans.f[i]=s/b; 67 if(ans.f[i])end=max(end,i); 68 k=s%b; 69 } 70 ans.f[0]=end; 71 return ans; 72 } 73 }; 74 char s[2005]; 75 big_num read() { 76 lol i,j,len,cnt=0; 77 big_num ans; 78 scanf("%s",s+1); 79 len=strlen(s+1); 80 for(i=len; i>=1; i-=8) { 81 cnt++; 82 j=i-7; 83 if(j<=1)j=1; 84 for(j; j<=i; j++) { 85 ans.f[cnt]=ans.f[cnt]*10+s[j]-'0'; 86 } 87 } 88 ans.f[0]=cnt; 89 return ans; 90 } 91 void print(big_num ans) { 92 printf("%lld",ans.f[ans.f[0]]); 93 lol i=ans.f[0]-1; 94 for(i; i>=1; i--) { 95 lol tot=mod/10; 96 while(ans.f[i]<tot) { 97 printf("0"); 98 tot/=10; 99 } 100 if(ans.f[i]!=0)printf("%lld",ans.f[i]); 101 } 102 printf("\n"); 103 } 104 big_num A(lol n,lol m) { 105 big_num ans,x; 106 ans.give(1ll); 107 x.clean(); 108 for(lol i=n; i>=n-m+1; i--) { 109 x.give(i); 110 ans=ans*x; 111 } 112 return ans; 113 } 114 int main() { 115 lol n,m; 116 scanf("%lld%lld",&n,&m); 117 big_num Ans=A(n,n)*A(n+1,2)*A(n+3,m)+A(n,n)*A(n+1,1)*A(2,2)*A(m,1)*A(n+2,m-1); 118 print(Ans); 119 return 0; 120 }