取模问题

来源:互联网 发布:it618淘宝客导购 编辑:程序博客网 时间:2024/06/16 07:50

快速指数幂取模:a^p%m


long long fun(long long a,long long p,long long m){    if(p==0)        return 1;    long long r=a%m;    long long k=1;    while(p>1)    {        if((p&1)!=0)        {            k=(k*r)%m;        }        r=(r*r)%m;        p>>=1;    }    return (r*k)%m;}


大数组合数取模:以C(n-m+1)取m为例

long long p,m,n;long long Pow(long long a,long long b){    long long ans=1;    while(b)    {        if(b&1)        {            b--;            ans=(ans*a)%p;        }        else        {            b/=2;            a=(a*a)%p;        }    }    return ans;}long long C(long long n,long long m){    if(n<m)        return 0;    long long ans=1;    for(int i=1;i<=m;i++)    {        ans=ans*(((n-m+i)%p)*Pow(i,p-2)%p)%p;    }    return ans;}long long Lucas(long long n,long long m){    if(m==0)        return 1;    return Lucas(n/p,m/p)*C(n%p,m%p)%p;}int main(){    while(scanf("%lld%lld%lld",&n,&m,&p)!=EOF)    {        printf("%lld\n",Lucas(n-m+1,m));    }    return 0;}

快速取组合数:Cn取m;
long long cal(long long n, long long m){    long long i, a, b, p;    if(n<m)    {        i=m;        m=n;        n=i;    }    p=1;    a=n-m<m?n-m:m;    b=n-m>m?n-m:m;    for(i=1; i<=a; i++)        p+=(p*b/i);    return p;}


今天在网上看见一道题目,感觉挺厉害似的,就是求一个数a的b次方在取摸c。但是独特之处在于b是一个非常大的数,可以有一千位等。就是b是一个大数:

源代码:

#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>#define LL long long#define nnum 1000005#define nmax 31625int flag[nmax], prime[nmax];int plen;void mkprime() {    int i, j;    memset(flag, -1, sizeof(flag));    for (i=2,plen=0; i<nmax; i++) {        if(flag[i]) {            prime[plen++]=i;        }        for (j=0; (j<plen)&&(i*prime[j]<nmax); j++) {            flag[i*prime[j]]=0;            if(i%prime[j]==0) {                break;            }        }    }}int getPhi(int n) {    int i, te, phi;    te=(int) sqrt(n * 1.0);    for (i=0,phi=n; (i<plen)&&(prime[i]<=te); i++) {        if (n%prime[i]==0) {            phi=phi/prime[i]*(prime[i]-1);            while (n%prime[i]==0) {                n/=prime[i];            }        }    }    if (n > 1)        phi = phi / n * (n - 1);    return phi;}int cmpCphi(int p, char *ch) {    int i, len;    LL res;    len=strlen(ch);    for (i=0, res=0; i<len; i++) {        res=(res*10+(ch[i]-'0'));        if (res>p) {            return 1;        }    }    return 0;}int getCP(int p, char *ch) {    int i, len;    LL res;    len=strlen(ch);    for (i=0,res=0; i<len; i++) {        res=(res * 10 + (ch[i] - '0')) % p;    }    return (int)res;}int modular_exp(int a, int b, int c) {    LL res, temp;    res=1%c,temp=a%c;    while (b) {        if (b&1)            res=res*temp%c;        temp=temp*temp%c;        b>>=1;    }    return (int)res;}void solve(int a,int c,char *ch) {    int phi,res,b;    phi=getPhi(c);    if(cmpCphi(phi, ch))        b=getCP(phi,ch)+phi;    else        b=atoi(ch);    res=modular_exp(a,b,c);    printf("%d\n",res);}//求解(a^b)%c;  b是大数int main() {    int a, c;    char ch[nnum];    mkprime();    while (~scanf("%s",ch)) {        int len=strlen(ch);        int d=len-1;        while (ch[d] =='0') {            ch[d] = '9';            d--;        }        ch[d]--;        a=2;        c=1000000007;        solve(a%c,c,ch);    }    return 0;}








原创粉丝点击