题目大意:求C(n+m,n)去掉末尾所有的0之后的后k位
组合数取模问题……首先k<=9,所以我们考虑直接mod 10^9
将10^9分解质因数,可以得到10^9=2^9*5^9=512*1953125 这两个数都不是很大 所以直接套用组合数取模的模板
具体细节参见 2142 礼物 http://blog.csdn.net/popoqqq/article/details/39891263
消0的时候注意消掉2的时候要乘上相应5的逆元 消5同理
#include <cstdio> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define P1 512ll #define P2 1953125ll using namespace std; typedef long long ll; typedef pair<ll,ll> abcd; ll n,m,k; ll power1[P1+1],power2[P2+1]; ll Quick_Power(ll x,ll y,ll p) { ll re=1; while(y) { if(y&1) re*=x,re%=p; x*=x,x%=p; y>>=1; } return re; } abcd Plus(const abcd x,const abcd y,ll p) { return abcd(x.first*y.first%p,x.second+y.second); } abcd Minus(const abcd x,const abcd y,ll p,ll phi_p) { return abcd(x.first*Quick_Power(y.first,phi_p-1,p)%p,x.second-y.second); } abcd Find(ll x,ll p,ll p_a,ll pow[]) { ll i,temp; if(!x) return abcd(1,0); temp=Quick_Power(pow[p_a],x/p_a,p_a)*pow[x%p_a]%p_a; return Plus(abcd(temp,x/p),Find(x/p,p,p_a,pow),p_a); } int main() { int i; power1[0]=power2[0]=1; for(i=1;i<=P1;i++) power1[i]=power1[i-1]*(i%2?i:1)%P1; for(i=1;i<=P2;i++) power2[i]=power2[i-1]*(i%5?i:1)%P2; cin>>n>>m>>k; abcd p1=Find(n+m,2,P1,power1); p1=Minus(p1,Find(n,2,P1,power1),P1,P1/2*1); p1=Minus(p1,Find(m,2,P1,power1),P1,P1/2*1); abcd p2=Find(n+m,5,P2,power2); p2=Minus(p2,Find(n,5,P2,power2),P2,P2/5*4); p2=Minus(p2,Find(m,5,P2,power2),P2,P2/5*4); ll temp=min(p1.second,p2.second); ll x=p1.first*Quick_Power(2,p1.second-temp,P1)%P1*Quick_Power(205,temp,P1)%P1; ll y=p2.first*Quick_Power(5,p2.second-temp,P2)%P2*Quick_Power(976563,temp,P2)%P2; ll ans=(1953125*109*x+512*1537323*y)%1000000000; cout<<setfill('0')<<setw(k)<<ans%Quick_Power(10,k,1000000001)<<endl; }