lucas数论定理学习

2015ICPC长春网络赛1010 考到了lucas+crt(中国剩余定理)

赛后补题ing。。

卢卡斯定理的百度百科

证明来自一本《初等数论》非常赞!


hdu3037

模板题

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#include 

using namespace std;
typedef long long ll;
const int maxn = 100001;
const int mod = 10007;
const int inf = 0x7f7f7f7f;
const double eps = 1e-4;

#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define pii pair

int N, M, P;
int aa[maxn];

int inv(int n,int p) {
    int m=1, k=p-2;
    while(k) {
        if(k&1) m=1ll*m*n%p;
        k>>=1; n=1ll*n*n%p;
    }
    return m;
}
int Cm(int n,int m,int p) {
    if(m>n) return 0;
    return aa[n]*1ll*inv(aa[m],p)*inv(aa[n-m],p)%p;
}
ll lucas(int n,int m,int p) {
    if(!m) return 1;
    return lucas(n/p,m/p,p)*Cm(n%p,m%p,p)%p;
}

int main() {
    int T; cin>>T; aa[0]=1;
    while(T--) {
        scanf("%d%d%d", &N, &M, &P);
        for(int i=1;i


hdu4349

 C(n,0),C(n,1),C(n,2)...C(n,n).里面有几个奇数

对于C(n,m)是否为奇数就是求C(n,m)%2,lucas~

n,m写成2进制:n=a[k]a[k-1]...a[0],m=b[k]b[k-1]...b[0]

如果存在一个a[i]C (n,m)%2=0

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#include 

using namespace std;
typedef long long ll;
const int maxn = 100001;
const int mod = 10007;
const int inf = 0x7f7f7f7f;
const double eps = 1e-4;

#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define pii pair

int N, M, P;
int aa[maxn];

int inv(int n,int p) {
    int m=1, k=p-2;
    while(k) {
        if(k&1) m=1ll*m*n%p;
        k>>=1; n=1ll*n*n%p;
    }
    return m;
}
int Cm(int n,int m,int p) {
    if(m>n) return 0;
    return aa[n]*1ll*inv(aa[m],p)*inv(aa[n-m],p)%p;
}
ll lucas(int n,int m,int p) {
    if(!m) return 1;
    return lucas(n/p,m/p,p)*Cm(n%p,m%p,p)%p;
}

int main() {
//    int T; cin>>T;
    while(~scanf("%d", &N)) {
        ;
        M=0;
        for(int i=1;i<=N;i<<=1) {
            if(N&i) M++;
        }
        printf("%d\n", 1<

hdu 3944


求杨辉三角中从顶点到(n,k)路径和(只能向下或右下,如图)的 路径和的最小值 mod p

例如样例4 2 路径为 (0,0) -> (2,0) -> (4,2)

只考虑终点在左半边的情况,对称可以求右半边

先是路径肯定是直线下降,然后一直右下到达终点,显然这种路只有一条

下降的部分全部为1

右下的部分为 (n-m,0) -> (n,m)

C(n-m,0) + ... + C(n,m)=C(n+1,m)

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#include 

using namespace std;
typedef long long ll;
const int maxn = 10001;
const int mod = 10007;
const int inf = 0x7f7f7f7f;
const double eps = 1e-4;

#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define pii pair

int N, M, P, K;
//int aa[maxn];
int aap[1230][maxn];

int inv(int n,int p) {
    int m=1, k=p-2;
    while(k) {
        if(k&1) m=m*n%p;
        k>>=1; n=n*n%p;
    }
    return m;
}
int Cm( int n,int m,int p) {
    if(m>n) return 0;
    return aap[K][n]*1ll*inv(aap[K][m],p)*inv(aap[K][n-m],p)%p;
}
int lucas(int n,int m,int p) {
    if(!m) return 1;
    return lucas(n/p,m/p,p)*Cm(n%p,m%p,p)%p;
}
int prim[maxn];
int main() {
//    int T; cin>>T;
    for(int i=2;iN) M=N-M;
        K=lower_bound(prim+1,prim+prim[0],P)-prim;
        printf("%d\n", (lucas(N+1,M,P)+N-M)%P );
    }
    return 0;
}



你可能感兴趣的:(lucas定理,组合数学,数论)