exlucas

i128 作为下标的时候会出现奇怪 ub!所以要先强转!

#include <bits/stdc++.h>
#define int __int128
#define pb push_back
//#define i64 long long
//#define
using namespace std;
int rd() {
    int f=1,sum=0; char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return sum*f;
}
void pr(int x) {
    static int st[10000]; int tot=0;
    if(x<0) {
        putchar('-'); x=-x;
    }
    if(x==0) {
        putchar('0'); return ;
    }
    while(x) st[++tot]=x%10,x/=10;
    for(int i=tot;i>=1;i--) putchar(st[i]+'0');
}
int n,m,P,pp[10000],A[10000],M[100000],mod,p,CT;
int t;
int fpow(int x,int y) {
    int res=1; x%=mod;
    while(y) {
        if(y&1) res=res*x%mod;
        y>>=1; x=x*x%mod;
    } return res;
}
int jie[5000005];
int sol(int n) {
    if(!n) return 1;
    if(n==1) return 1;
    int qwq=n/mod,res=sol(n/p);
//  pr(mod); putchar(' '); pr(n); putchar('\n');
    res=res*fpow(jie[mod],qwq)%mod;
//  cout<<n<<" "<<mod<<'\n';
//  for(int i=1;i<=n;i++) {
//      if(i%p) res=res*i%mod;
//  }
    for(int i=qwq*mod+1;i<=n;i++) {
        if(i%p) res=res*i%mod;
    }
//  for(int i=1;i<=n;i++) {
//      if(__gcd(i,p)==1) res=res*i%mod; 
//  }
    return res;
//  int res=1;
//  for(int i=1;i<=n;i++) {
//      int x=i;
//      while(__gcd(x,p)!=1) x/=p;
//      res=res*x%mod;
//  }return res;
}

int vp(int n) {
    int res=0;
    for(int i=p;;i*=p) {
//      pr(p); putchar('\n');
        if((n/i)==0) break ;
        res+=n/i;
    } return res;
}

//int baoli(int x) {
//  int res=1;
//  if(m<p) {   
//      for(int i=n-m+1;i<=n;i++) res=res*i%mod;
//      for(int i=1;i<=m;i++) res=res*fpow(i,mod-2)%mod;
//      return res; 
//  }
//  for(int i=m+1;i<=n;i++) res=res*i%mod;
//  for(int i=1;i<=n-m;i++) res=res*fpow(i,mod-2)%mod;
//  return res;
//}

pair<int,int>exgcd(int a,int b) {
    if(!b) {
        return make_pair(1,0);
    }
    auto qwq=exgcd(b,a%b);
    return make_pair(qwq.second,qwq.first-(a/b)*qwq.second);
}

int lcm(int x,int y) {
    return x/__gcd(x,y)*y;
}

int inv(int a) {
    auto qwq=exgcd(a,mod);
    return (qwq.first%mod+mod)%mod;
}

int get(int x) {
    mod=M[x]; p=pp[x]; jie[0]=1;
    for(int i=1;i<=mod;i++) {
        jie[i]=jie[i-1];
        if(i%p!=0) jie[i]=jie[i]*i%mod;
    }
//  if(n<p||m<p||n-m<p) {
//      return baoli(x);
//  }
    int res=vp(n)-vp(m)-vp(n-m);
    res=fpow(p,res);
    res=res*sol(n)%mod*inv(sol(n-m))%mod*inv(sol(m))%mod;
//  cout<<res<<" "<<baoli(x)<<'\n';
//  cout<<p<<" "<<mod<<" "<<res<<" "<<vp(n)-vp(m)-vp(n-m)<<'\n';
    return res;
}

signed main() {
//  cin.tie(0); ios::sync_with_stdio(false);
    n=rd(); m=rd(); P=rd();
    if(m>n) {
        cout<<"0"; return 0;
    }
    for(int i=2;i*i<=P;i++) {
        if(P%i) continue ;
        ++t; M[(short)t]=1; pp[(short)t]=i;
        while(P%i==0) M[t]*=i,P/=i;
    }
    if(P!=1) ++t,M[t]=P,pp[(short)t]=P;
    for(int i=1;i<=t;i++) {
        if(M[i]==0) {
            cout<<"wa";
        }
    }
    for(int i=1;i<=t;i++) A[i]=get(i);
    if(t==1) {
        A[1]=(A[1]%M[1]+M[1])%M[1];
        pr(A[1]); return 0;
    }
    int ans=A[1],MM=M[1];
    for(int i=2;i<=t;i++) {
//      cout<<A[i]<<'\n';
        int a=MM,b=M[i],C=(A[i]-ans%b+b)%b;
        int d=__gcd(a,b);
//      if(C%d) {
//          fl=0; break ;
//      }
        auto qwq=exgcd(MM,M[i]);
        int x=qwq.first;
        if(d==0) {
            cout<<"WA";
        }
        x=x*(C/d)%(M[i]/d);
        int q=lcm(MM,b);
        ans=(ans+x*MM%q)%q;
//      
        MM=q;ans=(ans%MM+MM)%MM;
    }
    pr(ans);
    return 0;
} 

原文链接: https://www.cnblogs.com/xugangfan/p/17067929.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    exlucas

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/314217

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月16日 下午1:12
下一篇 2023年2月16日 下午1:13

相关推荐