扩展CRT&&扩展lucas

来源:互联网 发布:大数据上市公司有几家 编辑:程序博客网 时间:2024/05/24 15:37

直接上板子,这里没有证明,只是提供一个还不错的板子
扩展CRT:

#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<cstdlib>#define ll long longusing namespace std;inline int read(){    int x=0;char ch=' ';ll f=1;    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();    if(ch=='-')f=-1,ch=getchar();    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();    return x*f;}const int N=1005;inline ll gcd(ll a,ll b){    if(!b)return a;    return gcd(b,a%b);}inline void exgcd(ll a,ll b,ll &x,ll &y){    if(!b){x=1,y=0;return;}    exgcd(b,a%b,y,x);    y-=a/b*x;}inline ll inv(ll a,ll p){    ll x,y;    exgcd(a,p,x,y);    if(x<0)x+=p;    return x;}ll n,c[N],m[N];inline ll CRT(){    for(int i=2;i<=n;i++){        ll m1=m[i-1],m2=m[i],c1=c[i-1],c2=c[i];        ll t=gcd(m1,m2);        m[i]=m1*m2/t;        c[i]=inv(m1/t,m2/t)*((c2-c1)/t)%(m2/t)*m1+c1;        c[i]=(c[i]%m[i]+m[i])%m[i];    }    return c[n];}int main(){    freopen("CRT3.in","r",stdin);    freopen("CRT3.out","w",stdout);    n=read();    for(int i=1;i<=n;i++)c[i]=read();    for(int i=1;i<=n;i++)m[i]=read();    printf("%lld",CRT());    return 0;}

扩展lucas:

#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<cstdlib>#define ll long longusing namespace std;inline ll read(){    ll x=0;char ch=' ';ll f=1;    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();    if(ch=='-')f=-1,ch=getchar();    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();    return x*f;}inline void print(ll x){    if(!x)return;    print(x/10);    putchar(x%10+'0');}inline void exgcd(ll a,ll b,ll &x,ll &y){    if(!b){x=1,y=0;return;}    exgcd(b,a%b,y,x);    y-=a/b*x;}inline ll inv(ll a,ll p){    ll x,y;    exgcd(a,p,x,y);    x=(x%p+p)%p;    if(!x)x+=p;    return x;}inline ll ksm(ll a,ll b,ll p){    ll ans=1;    while(b){        if(b&1)ans=(ans*a)%p;        a=(a*a)%p;        b>>=1;    }    return ans;}inline ll exlucas(ll n,ll pi,ll pk){    if(!n)return 1LL;    ll ans=1LL;    for(ll i=2LL;i<=pk;i++)if(i%pi)ans=(ans*i)%pk;    ans=ksm(ans,n/pk,pk);    for(ll i=2LL;i<=n%pk;i++)if(i%pi)ans=(ans*i)%pk;    return (ans*exlucas(n/pi,pi,pk))%pk;}inline ll C(ll n,ll m,ll pi,ll pk){    if(m>n)return 0LL;    ll a=exlucas(n,pi,pk),b=exlucas(n-m,pi,pk),c=exlucas(m,pi,pk);    ll ans,k=0;    for(ll i=n;i;i/=pi)k+=i/pi;    for(ll i=n-m;i;i/=pi)k-=i/pi;    for(ll i=m;i;i/=pi)k-=i/pi;    ans=a*inv(b,pk)%pk*inv(c,pk)%pk*ksm(pi,k,pk)%pk;    return ans;}ll T,n,m,p,P,ans;int main(){    T=read();    while(T--){        n=read();m=read();P=read();p=P;ans=0;        for(ll pi=2;pi*pi<=p;pi++){            if(p%pi==0){                ll pk=1LL;                while(p%pi==0){p/=pi;pk*=pi;}                ans=(ans+C(n,m,pi,pk)*(P/pk)%P*inv(P/pk,pk)%P)%P;            }        }        if(p>1)ans=(ans+C(n,m,p,p)*(P/p)%P*inv(P/p,p)%P)%P;        printf("%lld\n",ans);    }    return 0;}
原创粉丝点击