• Hdu 5446 Unknown Treasure (2015 ACM/ICPC Asia Regional Changchun Online Lucas定理 + 中国剩余定理)


    题目链接:

      Hdu 5446 Unknown Treasure

    题目描述:

      就是有n个苹果,要选出来m个,问有多少种选法?还有k个素数,p1,p2,p3,...pk,结果对lcm(p1,p2,p3.....,pk)取余。

    解题思路:

      Lucas + 中国剩余定理,注意的是中国剩余定理的时候有可能会爆long long。然后用一个快速加法就好辣。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 typedef __int64 LL;
      8 const int maxn = 20;
      9 
     10 LL quick_mul (LL a, LL b, LL mod)
     11 {
     12     LL res = 1;
     13     while (b)
     14     {
     15         if (b % 2)
     16             res = (res * a) % mod;
     17         a = (a * a) % mod;
     18         b /= 2;
     19     }
     20     return res;
     21 }
     22 
     23 LL quick_add (LL a, LL b, LL mod)
     24 {
     25     LL res = 0;
     26     while (b)
     27     {
     28         if (b % 2)
     29             res =(res + a) % mod;
     30         a = (a + a) % mod;
     31         b /= 2;
     32     }
     33     return res;
     34 }
     35 
     36 LL C (LL n, LL m, LL mod)
     37 {
     38     if (n < m)
     39         return 0;
     40     LL ans = 1;
     41     for (int i=1; i<=m; i++)
     42     {
     43         LL a = (n - m + i) % mod;
     44         LL b = i % mod;
     45         ans = ans * (a * quick_mul(b, mod - 2, mod) % mod) % mod;
     46     }
     47     return ans;
     48 }
     49 
     50 LL Extended_Euclid (LL a, LL b, LL &x, LL &y)
     51 {//a, b只能是正数
     52     if (b == 0)
     53     {
     54         x = 1;
     55         y = 0;
     56         return a;
     57     }
     58 
     59     LL r = Extended_Euclid (b, a%b, x, y), t;
     60     t = x;
     61     x = y;
     62     y = t - a / b * y;
     63     return r;
     64 }
     65 
     66 LL CRT (LL a[], LL b[], LL n)
     67 {
     68     LL M = 1, ans = 0;
     69     LL Mi, x, y;
     70 
     71     for (int i=0; i<n; i++)
     72         M *= a[i];
     73 
     74     for (int i=0; i<n; i++)
     75     {
     76         Mi = M / a[i];
     77         LL d = Extended_Euclid (Mi, a[i], x, y);
     78         x = (x % a[i] + a[i]) % a[i];
     79         //注意,这里的x有可能是负数要注意取mod,变成正的
     80         
     81         //或者quick_add 的第二个参数传Mi
     82         LL res = quick_add (x, Mi, M);
     83         res = quick_add (res, b[i], M);
     84         ans = (ans + res) % M;
     85     }
     86     return (ans + M) % M;
     87 }
     88 LL Lucas (LL n, LL m, LL mod)
     89 {
     90     if (m == 0)
     91         return 1;
     92     return (C(n%mod, m%mod, mod) * Lucas(n/mod, m/mod, mod)%mod);
     93 }
     94 
     95 int main ()
     96 {
     97     LL t, n, m, k, a[maxn], b[maxn];
     98     scanf ("%I64d", &t);
     99     while (t --)
    100     {
    101         scanf ("%I64d %I64d %I64d", &n, &m, &k);
    102         for (int i=0; i<k; i++)
    103         {
    104             scanf ("%I64d", &a[i]);
    105             b[i] = Lucas (n, m, a[i]);
    106         }
    107         printf ("%I64d
    ", CRT (a, b, k));
    108     }
    109     return 0;
    110 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    VS快速格式化代码
    EasyUI——实现展示后台数据代码
    并行开发
    EF---结合三层方法的应用
    EF—主键冲突解决办法
    SVN——配置和安装
    谈谈MVC模式
    JDK/Java里的设计模式
    设计模式的设计原则和精神
    举例说明你使用的设计模式
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4817572.html
Copyright © 2020-2023  润新知