现在的位置: 首页 > 综合 > 正文

HDU4373(组合公式推导+Lucas定理+中国剩余定理) HDU4373(组合公式推导+Lucas定理+中国剩余定理)

2017年11月04日 ⁄ 综合 ⁄ 共 2058字 ⁄ 字号 评论关闭

HDU4373(组合公式推导+Lucas定理+中国剩余定理)

分类: 数论 156人阅读 评论(0) 收藏 举报

题目:Mysterious For

 

题意:

m个for循环嵌套,有两种形式,第一类从1开始到n,第二类从上一层循环当前数开始到n,第一层一定是第一种类型,问总的循环的次数对364875103取余的结果。

首先可以看出,每一个第一类循环都是一个新的开始,与前面的状态无关,所以可以把m个嵌套分为几个不同的部分,每一个部分由第一类循环开始,最终结果相乘就可以。

剩下的就是第二类循环的问题,假设一个m层循环,最大到n,

只有第一层:循环n次。

只有前两层:循环n + (n - 1) + ... + 1 = (n + 1) * n / 2 = C(n + 1, 1)

只有前三层:

      (n + 1) * n / 2 + n * (n - 1) / 2 + ... + 1

    = (1 + 2 + ... + n) / 2 + (1 + 4 + ... + n^2) / 2

    = (n + 1) * n / 2 / 2 + n * (n + 1) * (2n + 1) / 6 / 2

    = (n + 2) * (n + 1) * n / 6 = C(n + 2, 2)

找规律得第m层:C(n + m - 1, m)

  1. #include <iostream>  
  2. #include <string.h>  
  3. #include <stdio.h>  
  4.   
  5. using namespace std;  
  6. typedef long long LL;  
  7.   
  8. const int N=25;  
  9. const int MOD1=97;  
  10. const int MOD2=3761599;  
  11. const int MOD=MOD1*MOD2;  
  12.   
  13. int m,n,k;  
  14. int a[N];  
  15. LL fac1[MOD1+10];  
  16. LL fac2[MOD2+10];  
  17. LL inv1,inv2;  
  18.   
  19. LL quick_mod(LL a,LL b,LL m)  
  20. {  
  21.     LL ans=1;  
  22.     a%=m;  
  23.     while(b)  
  24.     {  
  25.         if(b&1)  
  26.         {  
  27.             ans=ans*a%m;  
  28.             b--;  
  29.         }  
  30.         b>>=1;  
  31.         a=a*a%m;  
  32.     }  
  33.     return ans;  
  34. }  
  35.   
  36. LL C(LL n,LL m,LL p,LL fac[])  
  37. {  
  38.     if(n<m) return 0;  
  39.     return fac[n]*quick_mod(fac[m]*fac[n-m],p-2,p)%p;  
  40. }  
  41.   
  42. LL Lucas(LL n,LL m,LL p,LL fac[])  
  43. {  
  44.     if(m==0) return 1;  
  45.     return C(n%p,m%p,p,fac)*Lucas(n/p,m/p,p,fac);  
  46. }  
  47.   
  48. void Init()  
  49. {  
  50.     fac1[0]=fac2[0]=1;  
  51.     for(int i=1;i<MOD1;i++)  
  52.         fac1[i]=(fac1[i-1]*i)%MOD1;  
  53.     for(int i=1;i<MOD2;i++)  
  54.         fac2[i]=(fac2[i-1]*i)%MOD2;  
  55.     inv1=MOD2*quick_mod(MOD2,MOD1-2,MOD1);  
  56.     inv2=MOD1*quick_mod(MOD1,MOD2-2,MOD2);  
  57. }  
  58.   
  59. int main()  
  60. {  
  61.     Init();  
  62.     int t,tt=1;  
  63.     scanf("%d",&t);  
  64.     while(t--)  
  65.     {  
  66.         scanf("%d%d%d",&n,&m,&k);  
  67.         for(int i=0;i<k;i++)  
  68.              scanf("%d",&a[i]);  
  69.         a[k]=m;  
  70.         LL ans=1;  
  71.         for(int i=0;i<k;i++)  
  72.         {  
  73.             LL m1=Lucas(a[i+1]-a[i]+n-1,a[i+1]-a[i],MOD1,fac1);  
  74.             LL m2=Lucas(a[i+1]-a[i]+n-1,a[i+1]-a[i],MOD2,fac2);  
  75.             LL mm=(m1*inv1+m2*inv2)%MOD;  
  76.             ans=(ans*mm)%MOD;  
  77.         }  
  78.         printf("Case #%d: ",tt++);  
  79.         cout<<ans<<endl;  
  80.     }  
  81.     return 0;  
  82. }  

抱歉!评论已关闭.