等价于C(n,m)%p==0求m的个数
n!/(m!*(n-m)!)%p==0
N!中p的因子个数等于m!与(n-m)!中的p的因子和
即f(n) ==f(m)+f(n-m) //f(n)表示n!所含有的因子数
F(n)=n/p+n/(p^2)+....
即:
n/p+n/p^2+...=m/p+m/p^2+..+(n-m)/p+(n-m)/p^2+... (1)
又因为n/p^i>=m/p^i+(n-m)/p^i,
所以等价于对任意i都有n/p^i =m/p^i+(n-m)/p^i (2)
N=n/p^i*p^i+n%p^i(注意这里所有的除法都是整除)
(2)两边都乘以p^i
n-n%p^i=m-m%p^i+n-m+(n-m)%p^i
n%p^i-m%p^i=(n-m)%p^i>=0
又等价于 m%(p^i)<=n%(p^i) (3)对任意正整数i都成立。(//从2到3这个一步相当的重要,是本题的一个关键点)
将n和m分别写成P进制数 n0,n1,n2,n3,n4,.... m0,m1,m2,m3,m4,....
根据(3)可以由数学归纳法得到,对于任意位上的ni都大于等于mi
当i=0;显然成立
假设i=k成立,当i=k+1时
因为m%(p^k)<=n%(p^k)
n(k+1)nk..n1=n(k+1)(nk%(p^k))(表示按p进制摆放)
所以要保证n%(p^(k+1))>=m%(p^(k+1))
必须保证最高位即n(k+1)>=m(k+1)
即(3)成立的充要条件就是 m0<=n0, m1<=n1 ....
所以m的可取值个数就是(n0+1)*(n1+1)*(n2+1)......
//HDU 3304
#include<iostream>
using namespace std;
int main()
{
int n,p,ans,cs;
cs=0;
while(cin>>p>>n)
{
cs++;
if ( (n==0)&&(p==0) ) break;
ans=1;
while(n!=0)
{
ans=ans*(n%p+1)%10000;
n=n/p;
}
cout<<"Case "<<cs<<": ";
if (ans<1000) cout<<'0';
if (ans<100) cout<<'0';
if (ans<10) cout<<'0';
cout<<ans<<endl;
}
}