ztx

[HNOI2012]排队

Posted on 2015年1月13日 19:31
/****************************************\
* Author : ztx
* Title  : [HNOI2012]排队
* ALG    :
* CMT    :
    1 首先不考虑两个老师相邻的情况,即将老师看做男生,
      再用隔板法得到此时的方案数为
          P(n+2,n+2)*A(n+3,m)*P(m,m)
    2 再找出两个老师相邻的方案数.将两个老师看做一个人,
      再用隔板法得到方案数为
          P(n+1,n+1)*P(2,2)*A(n+2,m)*P(m,m)
    3 将两个数相减得到答案,最终化简为
          ans = (n*n+3*n+2*m) * Π(1,n+1) * Π(n-m+4,n+2)
* Time   :
\****************************************/
/****************************************\
* Author : ztx
* Title  : [HNOI2012]排队
* ALG    :
* CMT    :
    1 首先不考虑两个老师相邻的情况,即将老师看做男生,
      再用隔板法得到此时的方案数为
          P(n+2,n+2)*A(n+3,m)*P(m,m)
    2 再找出两个老师相邻的方案数.将两个老师看做一个人,
      再用隔板法得到方案数为
          P(n+1,n+1)*P(2,2)*A(n+2,m)*P(m,m)
    3 将两个数相减得到答案,最终化简为
          ans = (n*n+3*n+2*m) * Π(1,n+1) * Π(n-m+4,n+2)
* Time   :
\****************************************/

#include <cstdio>
#include <cstring>

typedef long long ll ;

#define  max(x,y) ((x)>(y)?(x):(y))
#define  hpsize   10000LL
#define  width    10000LL

struct HP {
	int size ;
	int a[hpsize] ;
	HP() { size = 1 ; a[1] = 0 ; }
	void Assign(int x) { size = 0 ; while (x) { a[++size] = x%width ; x /= width ; } }
	HP operator * (const int b) const {
		HP ret ;
		int i , x = 0 ;
		for (i = 1 ; i <= size ; i ++ ) ret.a[i] = a[i]*b ;
		for (ret.size = 1 ; ret.size<=size || x ; ret.size ++ ) {
			ret.a[ret.size] += x ;
			x = ret.a[ret.size]/width ;
			ret.a[ret.size] %= width ;
		}
		while (!ret.a[ret.size] && ret.size>1) ret.size -- ;
		return ret ;
	}
	void Print() {
	    printf("%d", a[size]);
	    for (int i = size-1 ; i > 0 ; i -- ) printf("%04d", a[i] ) ;
	}
} ;

HP ans ;
int n , m , i ;

int main() {
	#define READ
	#ifdef  READ
		freopen("bzoj_2729.in" ,"r",stdin ) ;
		freopen("bzoj_2729.out","w",stdout) ;
	#endif
	scanf("%d%d", &n , &m ) ;
	if (m > n+3) { putchar('0') ; goto END ; }
	ans.Assign(n*n+3*n+2*m) ;
	for (i = 1 ; i <= n+1 ; i ++ ) ans = ans*i ;
	for (i = n-m+4 ; i <= n+2 ; i ++ ) ans = ans*i ;
	ans.Print() ;
	END : ;
	#ifdef  READ
		fclose(stdin) ; fclose(stdout) ;
	#else
		getchar() ; getchar() ;
	#endif
	return 0 ;
}