zoukankan      html  css  js  c++  java
  • 2014年百度之星程序设计大赛

    题目链接

    分析:打表以后就能发现时卡特兰数, 但是有除法取余。

    f[i] = f[i-1]*(4*i - 2)/(i+1);

    看了一下网上的题解,照着题解写了下面的代码,不过还是不明白,为什么用扩展gcd, 不是用逆元吗。。

    网上还有别人的解释,没看懂,贴一下:

     (a / b) % m = ( a % (m*b)) / b

    笔者注:鉴于ACM题目特别喜欢M=1000000007,为质数:

    当gcd(b,m) = 1, 有性质: (a/b)%m = (a*b^-1)%m, 其中b^-1是b模m的逆元.

    求出b相对于m的逆元b^(-1),即b*(b^(-1)) = 1 (mod m)。有b*b^(-1) - km = 1,其中k是一整数. 用Extended Euclid算法可以求出`b^(-1)。然后计算a*b^(-1) mod m = ( (a%m) * (b^(-1)%m ) % m; 其值与(a/b) mod m相同

    推导:a/b = x (mod m) --两边同乘一个数--> a = bx (mod m) ---x=b^-1a-> a = (b^-1) ba (mod m)

    再利用b^-1*b = 1(mod m) . 所以可以得出 x = b^-1*a是成立的。

         所以 (a/b) mod m 的解与 (a*b^-1)%m的解是一样的。 而后着可以利用模对乘法的线性性

    AC代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #define LL __int64
     7 using namespace std;
     8 const int mo = 1000000000 + 7;
     9 const int maxn = 1000000 + 10;
    10 LL f[maxn];
    11 
    12 LL exgcd(LL a,LL b,LL &x,LL &y)
    13 {
    14     if(b==0)
    15     {
    16         x=1; y=0; return a;
    17     }
    18     LL d = exgcd(b,a%b,x,y);
    19     LL t=x;
    20     x=y;
    21     y=t-a/b*y;
    22     return d;
    23 }
    24 void init()
    25 {
    26     int i;
    27     LL x, y;
    28     f[0] = f[1] = 1;
    29     for(i = 2; i < maxn-5; i++)
    30     {
    31         f[i] = f[i-1]*(4*i-2)%mo;
    32         exgcd(i+1, mo, x, y);
    33         f[i] = (f[i]*((x+mo)%mo))%mo;
    34     }
    35 }
    36 int main()
    37 {
    38     int t, n, ca = 1;
    39     init();
    40     scanf("%d", &t);
    41     while(t--)
    42     {
    43         scanf("%d", &n);
    44         printf("Case #%d:
    ", ca++);
    45         printf("%I64d
    ", f[n]);
    46     }
    47     return 0;
    48 }

    扩展gcd:

     1 //扩展 GCD  
     2  //求x, y使得gcd(a, b) = a * x + b * y;  
     3 
     4 int extgcd(int a, int b, int & x, int & y)
     5 { 
     6     if (b == 0) { x=1; y=0; return a; } 
     7     int d = extgcd(b, a % b, x, y); 
     8     int t = x; x = y; y = t - a / b * y; 
     9     return d; 
    10 } 
  • 相关阅读:
    codeblocks 更换颜色主题
    python3 回顾笔记1
    linux查找目录下的所有文件中是否含有某个字符串
    jupyter notebook 远程访问
    ubuntu ufw防火墙
    加载大量的xml数据 使用压缩方法解决(当然较小时也可以压缩)
    lua string介绍
    Lua和C++交互详细总结
    编写高性能的 Lua 代码
    lua中遍历table的几种方式比较
  • 原文地址:https://www.cnblogs.com/bfshm/p/3753160.html
Copyright © 2011-2022 走看看