zoukankan      html  css  js  c++  java
  • [国家集训队] 礼物

    Description

    给定P,求(Pi_{i=1}^m C_{n-w_1-w_2-...-w_{i-1}}^{w_i};mod;P)(mleq 5)

    Solution

    扩展Lucas的板子。
    P不是质数的话可以先质因数分解,然后求出同余每个质数次幂的解,再CRT合并就吼了
    (n!)怎么求还是注意一下吧,要先把和(p_i)不互质的部分拎出来算。拎出来的代码大概就是这样

    for(int i=n;i;i/=c[cur])
        now+=i/c[cur];
    

    别的就没啥了。突然发现自己数论忘了好多,都是看的自己之前写的博客。

    Code

    #include<cmath>
    #include<cctype>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using std::min;
    using std::max;
    using std::swap;
    #define int long long
    
    int p[100005],c[100005];
    int P,w[10],tot,a[100005];
    
    int exgcd(int a,int b,int &x,int &y){
        if(!b){
            x=1,y=0;
            return a;
        } int d=exgcd(b,a%b,y,x);
        y-=a/b*x;return d;
    }
    
    int inv(int a,int b){
        int x,y;
        exgcd(a,b,x,y);
        return (x%b+b)%b;
    }
    
    int getint(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch))w|=ch=='-',ch=getchar();
        while( isdigit(ch))X=X*10+ch-48,ch=getchar();
        return w?-X:X;
    }
    
    int ksm(int a,int b,int c){
        int ans=1;
        while(b){
            if(b&1) ans=ans*a%c;
            a=a*a%c;b>>=1;
        } return ans;
    }
    
    void fj(int P){
        int sq=sqrt(P);
        for(int i=2;i<=sq;i++){
            if(P%i==0){
                c[++tot]=i;
                while(P%i==0)
                    p[tot]++,P/=i;
                p[tot]=ksm(i,p[tot],1e9+2);
            }
        } if(P!=1)
            c[++tot]=P,p[tot]=P;
    }
    
    int solve(int x,int cur){
        if(!x) return 1;
        int now=1;
        for(int i=2;i<p[cur];i++){
            if(i%c[cur])
                now=now*i%p[cur];
        }
        now=ksm(now,x/p[cur],p[cur]);
        int q=x%p[cur];
        for(int i=2;i<=q;i++){
            if(i%c[cur])
                now=now*i%p[cur];
        }
        return now*solve(x/c[cur],cur)%p[cur];
    }
    
    int C(int n,int m,int cur){
        if(n<m) return 0;
        if(n==m) return 1;
        int now=0;
        for(int i=n;i;i/=c[cur])
            now+=i/c[cur];
        for(int i=m;i;i/=c[cur])
            now-=i/c[cur];
        for(int i=n-m;i;i/=c[cur])
            now-=i/c[cur];
        int a=solve(n,cur),b=solve(m,cur),cc=solve(n-m,cur);
        return a*inv(b,p[cur])%p[cur]*inv(cc,p[cur])%p[cur]*ksm(c[cur],now,p[cur])%p[cur];
    }
    
    int CRT(){
        int ans=0;
        for(int i=1;i<=tot;i++)
            ans=(ans+a[i]*(P/p[i])*inv(P/p[i],p[i]))%P;
        return ans;
    }
    
    signed main(){
        P=getint();fj(P);
        int n=getint(),m=getint(),cnt=0;
        for(int i=1;i<=m;i++)
            w[i]=getint(),cnt+=w[i];
        if(cnt>n) return printf("Impossible"),0;
        int ans=1,sum=n;
        for(int i=1;i<=m;i++){
            for(int j=1;j<=tot;j++)
                a[j]=C(sum,w[i],j);
            // printf("CRT=%lld
    ",CRT());
            ans=ans*CRT()%P;
            sum-=w[i];
        } printf("%lld
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    Microsoft Visual Studio 2010(vs10)安装与使用
    961专业课复习资料
    spring boot: 输出json
    spring boot: 热部署(一) run as – java application (spring-loader-1.2.4.RELEASE.jar)
    FastJson/spring boot: json输出方法二
    FastJson/spring boot: json输出
    FastJson中文乱码
    FastJSON 简单使用
    mytabits表关联一对一(多对一?)
    Model/ModelMap 和 ModelAndView 的区别使用
  • 原文地址:https://www.cnblogs.com/YoungNeal/p/9678798.html
Copyright © 2011-2022 走看看