zoukankan      html  css  js  c++  java
  • BZOJ 3129 SDOI2013 方程

    如果没有限制,答案直接用隔板法C(m-1,n-1)

    对于>=x的限制,我们直接在对应位置先放上x-1即可,即m=m-(x-1)

    对于<=x的限制,由于限制很小我们可以利用容斥原理将它转化为上面的>=x的限制

    即减去1个不满足的 加上2个不满足的 减去3个不满足的 ……

    之后就是组合数的计算,对于一个非常大的模数,我们可以将它唯一分解,之后CRT还原即可

    但是我们有可能不存在逆元,数据范围不允许我们递推计算组合数

    我们知道没有逆元当且仅当(a,p)不互素,我们可以将阶乘分成两部分:互素和不互素

    互素的部分具有循环节,我们暴力计算循环节之后快速幂即可

    不互素的部分我们可以提出他们的gcd出来并记录指数,剩余部分又变成了计算阶乘,递归即可

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
     
    const int maxn=110;
    typedef long long LL;
    int T,tot=0;
    LL p,n,n1,n2,m;
    LL mod[maxn],prime[maxn],a[maxn];
    LL Num[maxn];
    LL x,y,d;
    LL ans;
     
    void Get_mod(LL x){
        for(int i=2;i*i<=x;++i){
            if(x%i==0){
                prime[++tot]=i;mod[tot]=1;
                while(x%i==0){x/=i;mod[tot]*=i;}
            }
        }
        if(x>1)prime[++tot]=x,mod[tot]=x;
    }
    void ex_gcd(LL a,LL b,LL &x,LL &y,LL &d){
        if(b==0){x=1;y=0;d=a;}
        else{ex_gcd(b,a%b,y,x,d);y-=(a/b)*x;}
    }
    LL pow_mod(LL v,LL p,LL mod){
        LL tmp=1;
        while(p){
            if(p&1)tmp=tmp*v%mod;
            v=v*v%mod;p>>=1;
        }return tmp;
    }
    LL inv(LL a,LL b){
        ex_gcd(a,b,x,y,d);
        return (x%b+b)%b;
    }
    LL CRT(){
        LL ans=0;
        for(int i=1;i<=tot;++i){
            LL m=p/mod[i];
            ex_gcd(mod[i],m,d,y,d);
            ans=(ans+y*m*a[i])%p;
        }return (ans+p)%p;
    }
    pair<LL,LL> fac(int k,LL n){
        if(n==0)return make_pair(0,1);
        int x=n/prime[k],y=n/mod[k];
        LL ans=1;
        if(y){
            for(int i=2;i<mod[k];++i)if(i%prime[k]!=0)ans=(ans*1LL*i)%mod[k];
            ans=pow_mod(ans,y,mod[k]);
        }
        for(int i=y*mod[k]+1;i<=n;++i)if(i%prime[k]!=0)ans=(ans*1LL*i)%mod[k];
        pair<LL,LL> tmp=fac(k,x);
        return make_pair(x+tmp.first,ans*tmp.second%mod[k]);
    }
    LL cal(int k,LL n,LL m){
        if(n<m)return 0;
        pair<LL,LL> a=fac(k,n),b=fac(k,m),c=fac(k,n-m);
        return pow_mod(prime[k],a.first-b.first-c.first,mod[k])*a.second%mod[k]
        *inv(b.second,mod[k])%mod[k]*inv(c.second,mod[k])%mod[k];
    }
    LL C(LL n,LL m){
        for(int i=1;i<=tot;++i)a[i]=cal(i,n,m);
        return CRT();
    }
    void DFS(int pos,int now,LL sum){
        if(pos>n1){
            if(now)ans-=C(m-1-sum,n-1);
            else ans+=C(m-1-sum,n-1);
            ans=(ans+p)%p;
            return;
        }
        DFS(pos+1,now,sum);
        DFS(pos+1,now^1,sum+Num[pos]);
    }
     
    int main(){
        scanf("%d%lld",&T,&p);
        Get_mod(p);
        while(T--){
            scanf("%lld%lld%lld%lld",&n,&n1,&n2,&m);
            for(int i=1;i<=n1;++i)scanf("%lld",&Num[i]);
            for(int i=1;i<=n2;++i){scanf("%lld",&x);m=m-x+1;}
            ans=0;
            DFS(1,0,0);
            printf("%lld
    ",(ans+p)%p);
        }return 0;
    }
    

      

  • 相关阅读:
    linux下安装配置DHCP服务器
    CentOS7安装配置Apache HTTP Server
    CentOS7安装配置DNS服务器
    CentOS7安装配置SAMBA服务器
    小程序全局监听
    springboot+redis
    java对接微信小程序
    获取上一个页面的data
    定时器
    maven项目打包
  • 原文地址:https://www.cnblogs.com/joyouth/p/5392853.html
Copyright © 2011-2022 走看看