51nod 1120 Lucas定理

来源:互联网 发布:网络推广经理职责 编辑:程序博客网 时间:2024/06/05 20:10

题目就不说了
这题是一个经典的卢卡斯定理的运用,从左上走到右下,维护只能走下或上,其实就是类似V2V1,但是不能经过对角线,即障碍物,那么组合数乱搞就可以了,然而摸数太小,于是我们用lucas定理。
原理:C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p;
递归算就可以了,注意求逆元,线性或者exgcd都可以。

const mo=10007;var    i,j,k,p,m:longint;    fac:Array[0..200000]of int64;    x,y,n,ans:int64;function pow(a,b:int64):int64;var    base,r:int64;begin    base:=a;    r:=1;    while b<>0 do    begin        if b and 1<>0 then r:=r*Base mod mo;        base:=base*Base mod mo;        b:=b div 2;    end;    exit(r);end;procedure exgcd(a,b:int64;var x,y:int64);var    x1,y1:int64;begin    if b=0 then    begin        x:=1;        y:=0;        exit;    end;    exgcd(b,a mod b,x1,y1);    x:=y1;    y:=x1-(a div b)*y1;end;function lucas(n,m,p:int64):int64;var    ans,a,b:int64;begin    ans:=1;    while (n<>0)and(m<>0)do    begin        a:=n mod p;        b:=m mod p;        if a<b then exit(0);        ans:=((ans*fac[a]mod p)*(pow(fac[b]*fac[a-b]mod p,p-2)))mod p;                n:=n div p;                m:=m div p;    end;        exit(ans); end;begin    readln(n);    fac[0]:=1;    for i:=1 to mo do    fac[i]:=fac[i-1]*i mod mo;    exgcd(n,mo,x,y);    x:=(x mod mo+mo)mod mo;    x:=x<<1;    ans:=lucas(2*n-2,n-1,mo);    ans:=(ans*x)mod mo;    writeln(ans);end.
0 0
原创粉丝点击