• bzoj千题计划267:bzoj3129: [Sdoi2013]方程


    http://www.lydsy.com/JudgeOnline/problem.php?id=3129

    如果没有Ai的限制,就是隔板法,C(m-1,n-1)

    >=Ai 的限制:m减去Ai

    <=Ai 的限制:容斥原理,总数- 至少有一个数>Ai + 至少有两个数>Ai - ……

    计算组合数取模,模数虽然很大也不是质数,但是质因数分解后 最大的才 10201,所以用扩展卢卡斯即可 

    注意在用扩展卢卡斯计算 阶乘的时候,要预处理 不包含当前质因子的阶乘,否则会TLE 3个点

    #include<cstdio>
    #include<iostream>
    
    using namespace std;
    
    typedef long long LL;
    
    LL p;
    
    int up[9],down[9];
    
    int num;
    int PI[10001],PK[10001];
    
    LL fac[10202];
    
    template<typename T>
    void read(T &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    void pre()
    {
        LL t=p;
        for(LL i=2;i*i<=p;++i)
            if(!(t%i))
            {
                PI[++num]=i;
                PK[num]=1;
                while(!(t%i)) t/=i,PK[num]*=i;
            }
        if(t>1) 
        {
            PI[++num]=t;
            PK[num]=t;
        }
    }
    
    LL Pow(LL a,LL b,LL mod)
    {
        LL res=1;
        for(;b;b>>=1,a=a*a%mod)
            if(b&1) res=res*a%mod;
        return res;
    }
    
    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;
    }
    
    LL get_inv(LL a,LL b)
    {
        LL x,y;
        exgcd(a,b,x,y);
        x=(x%b+b)%b;
        return x;
    }
    
    LL get_fac(int n,LL pk,LL pi)
    {
        if(!n) return 1;
        LL ans=1;
        if(n/pk) ans=Pow(fac[pk],n/pk,pk);
        ans=ans*fac[n%pk]%pk;
        return ans*get_fac(n/pi,pk,pi)%pk;
    }
    
    LL exlucas(int n,int m,LL pk,LL pi)
    {
        fac[0]=1;
        for(int i=1;i<=pk;++i)
        {
            fac[i]=fac[i-1];
            if(i%pi) fac[i]=fac[i]*i%pk;
        }
        LL fn=get_fac(n,pk,pi);
        LL fm=get_fac(m,pk,pi);
        LL fnm=get_fac(n-m,pk,pi);
        LL k=0;
        for(int i=n;i;i/=pi) k+=i/pi;
        for(int i=m;i;i/=pi) k-=i/pi;
        for(int i=n-m;i;i/=pi) k-=i/pi;
        LL ans=fn*get_inv(fm,pk)%pk*get_inv(fnm,pk)%pk*Pow(pi,k,pk)%pk;
        return ans*(p/pk)%p*get_inv(p/pk,pk)%p;
    }
    
    LL get_C(int n,int m)
    {
        if(n<m) return 0;
        LL ans=0;
        LL pk;
        for(int i=1;i<=num;++i) 
            ans=(ans+exlucas(n,m,PK[i],PI[i]))%p;
        return ans;
    }
    
    int main()
    {
        freopen("equation.in","r",stdin);
        freopen("equation.out","w",stdout);
        int T; 
        read(T); read(p);
        pre();
        int n,n1,n2,m;
        int mm,t;
        LL ans=0;
        while(T--)
        {
            read(n); read(n1); read(n2); read(m);
            for(int i=1;i<=n1;++i) read(up[i]);
            for(int i=1;i<=n2;++i) read(down[i]);
            for(int i=1;i<=n2;++i) m-=down[i]-1;
            ans=0;
            for(int i=0;i<(1<<n1);++i)
            {
                mm=m;
                t=0;
                for(int j=1;j<=n1;++j)
                    if(i&(1<<j-1)) mm-=up[j],++t;
                t=(t&1) ? -1 : 1;
                ans=(ans+t*get_C(mm-1,n-1)+p)%p;
            }
            cout<<ans<<'
    ';
        }
    }

    3129: [Sdoi2013]方程

    Time Limit: 30 Sec  Memory Limit: 256 MB
    Submit: 646  Solved: 375
    [Submit][Status][Discuss]

    Description

    给定方程
        X1+X2+. +Xn=M
    我们对第l..N1个变量进行一些限制:
    Xl < = A
    X2 < = A2
    Xn1 < = An1
    我们对第n1 + 1..n1+n2个变量进行一些限制:
    Xn1+l > = An1+1
    Xn1+2 > = An1+2
    Xnl+n2 > = Anl+n2
    求:在满足这些限制的前提下,该方程正整数解的个数。
    答案可能很大,请输出对p取模后的答案,也即答案除以p的余数。

    Input

        输入含有多组数据,第一行两个正整数T,p。T表示这个测试点内的数据组数,p的含义见题目描述。
        对于每组数据,第一行四个非负整数n,n1,n2,m。
        第二行nl+n2个正整数,表示A1..n1+n2。请注意,如果n1+n2等于0,那么这一行会成为一个空行。

    Output

      共T行,每行一个正整数表示取模后的答案。

    Sample Input

    3 10007
    3 1 1 6
    3 3
    3 0 0 5

    3 1 1 3
    3 3

    Sample Output

    3
    6
    0

    【样例说明】
    对于第一组数据,三组解为(1,3,2),(1,4,1),(2,3,1)
    对于第二组数据,六组解为(1,1,3),(1,2,2),(1,3,1),(2,1,2),(2,2,1),(3,1,1)

    HINT

    n < = 10^9  , n1 < = 8   , n2 < = 8   ,  m < = 10^9  ,p<=437367875


    对于l00%的测试数据:  T < = 5,1 < = A1..n1_n2  < = m,n1+n2 < = n

  • 相关阅读:
    webpack:loader编写
    架构之路:从概念开始
    AtCoder Regular Contest 114(A-C)
    12-UE4-控件类型
    10-UE4-蓝图定义简介
    11-UE4-UMG UI设计器
    UE4-目录结构简介
    UE4-字符串
    官方Spring Boot starters整理
    Java是引用传递还是值传递?
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8535136.html
Copyright © 2020-2023  润新知