zoukankan      html  css  js  c++  java
  • 【拓展卢卡斯】LuoGu P2183 [国家集训队]礼物

    这是一道CTSC水题

    题目描述

    一年一度的圣诞节快要来到了。每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物。不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多。小E从商店中购买了n件礼物,打算送给m个人,其中送给第i个人礼物数量为wi。请你帮忙计算出送礼物的方案数(两个方案被认为是不同的,当且仅当存在某个人在这两种方案中收到的礼物不同)。由于方案数可能会很大,你只需要输出模P后的结果。

    输入输出格式

    输入格式:

     

    输入的第一行包含一个正整数P,表示模;

    第二行包含两个整整数n和m,分别表示小E从商店购买的礼物数和接受礼物的人数;

    以下m行每行仅包含一个正整数wi,表示小E要送给第i个人的礼物数量。

     

    输出格式:

     

    若不存在可行方案,则输出“Impossible”,否则输出一个整数,表示模P后的方案数。

     

    输入输出样例

    输入样例#1: 复制
    100
    4 2
    1
    2
    输出样例#1: 复制
    12
    输入样例#2: 复制
    100
    2 2
    1
    2
    输出样例#2: 复制
    Impossible
    

    说明

    【样例说明】

    下面是对样例1的说明。

    以“/”分割,“/”前后分别表示送给第一个人和第二个人的礼物编号。12种方案详情如下:

    1/23 1/24 1/34

    2/13 2/14 2/34

    3/12 3/14 3/24

    4/12 4/13 4/23

    设P=p1^c1 * p2^c2 * p3^c3 * … *pt ^ ct,pi为质数。

    对于15%的数据,n≤15,m≤5,pi^ci≤10^5;

    在剩下的85%数据中,约有60%的数据满足t≤2,ci=1,pi≤10^5,约有30%的数据满足pi≤200。

    对于100%的数据,1≤n≤10^9,1≤m≤5,1≤pi^ci≤10^5,1≤P≤10^9。

    这个思路真的是很水很水很水

    思路学过组合数的都能想出来,这道题主要就是要会exlucas,可以看我的博客点这里

    唯一注意的就是不要手残,不写函数名,用一个括号括上几个变量,因为这样不会CE但是得调试半天(我真是瞎了QAQ)

    上代码!

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define lt long long
      4 #define rt register lt 
      5 #define il inline
      6 using namespace std;
      7 lt p,n,m,w,tot,ans=1;
      8 namespace misaki
      9 {
     10     il lt gcd(lt a,lt b){return b?gcd(b,a%b):a;}
     11     il lt lcm(lt a,lt b){return a/gcd(a,b)*b;}
     12     il lt ksc(lt a,lt b,lt mod)
     13     {
     14         if(a==0||b==0)return 0;
     15         lt fina=0,kk=1;
     16         if(a<0)a=-a,kk=-kk;
     17         if(b<0)b=-b,kk=-kk;
     18         while(b)
     19         {
     20             if(b%2)fina=(fina+a)%mod;
     21             b>>=1,a=(a+a)%mod;
     22         }    
     23         return fina%mod*kk;
     24     }
     25     il lt ksm(lt a,lt k,lt mod)
     26     {
     27         if(!k)return 1;
     28         lt fina=1;
     29         while(k)
     30         {
     31             if(k%2)fina=ksc(fina,a,mod);
     32             k>>=1,a=(a*a)%mod;
     33         }    
     34         return fina%mod;
     35     }
     36     il void ex_gcd(lt a,lt b,lt &x,lt &y)
     37     {
     38         if(!b)x=1,y=0;
     39         else
     40         {
     41             ex_gcd(b,a%b,x,y);
     42             lt tt=x;x=y,y=tt-a/b*x;
     43         }
     44     }
     45     il lt exgcd(lt a,lt b,lt c)
     46     {
     47         lt gc=gcd(a,b),x=0,y=0;
     48         if(c%gc){    printf("aaa");return -1;}
     49         a/gc,b/=gc,c/=gc;
     50         ex_gcd(a,b,x,y);
     51         return (x*c%b+b)%b;
     52     }
     53     il lt inv(lt a,lt p)
     54     {
     55         if(!a)return 0;
     56         return exgcd(a,p,1);
     57     }
     58 }
     59 namespace lucas
     60 {
     61     using namespace misaki;
     62     il lt fac(const lt n,const lt pi,const lt pk)//n!%p^k
     63     {
     64         if(n==1||n==0)return 1;
     65         lt ans=1;
     66         for(rt i=2;i<pk;i++)
     67             if(i%pi)ans=ans*i%pk;
     68         ans=ksm(ans,n/pk,pk);
     69         for(rt i=2;i<=n%pk;i++)
     70             if(i%pi)ans=ans*i%pk;
     71         return ksc(ans,fac(n/pi,pi,pk),pk);
     72     }
     73     il lt C(const lt n,const lt m,const lt pi,const lt pk)//C(n,m)%p^k
     74     {
     75         lt up=fac(n,pi,pk),dl=fac(m,pi,pk),dr=fac(n-m,pi,pk),sum=0;
     76         for(rt i=n;i;i/=pi)sum+=i/pi;
     77         for(rt i=m;i;i/=pi)sum-=i/pi;
     78         for(rt i=n-m;i;i/=pi)sum-=i/pi;
     79         return up*inv(dl,pk)%pk*inv(dr,pk)%pk*ksm(pi,sum,pk)%pk;
     80     }
     81     il lt exlucas(const lt n,const lt m,const lt P)
     82     {
     83         lt tt=P,ans=0;
     84         for(rt i=2;i<=tt;i++)
     85             if(tt%i==0)
     86             {
     87                 lt pi=i,pk=1;
     88                 while(!(tt%i))tt/=i,pk*=i;
     89                 ans=(ans+C(n,m,pi,pk)*(P/pk)%P*inv(P/pk,pk)%P)%P;
     90             }
     91         return ans%P;
     92     }
     93 }
     94 int main()
     95 {
     96     scanf("%lld%lld%lld",&p,&n,&m);bool fl=0;
     97     for(rt i=1;i<=m;i++)
     98     {
     99         scanf("%lld",&w);
    100         if(n<w){fl=1;break;}tot+=w,ans=(ans*lucas::exlucas(n,w,p))%p,n-=w;
    101     }
    102     if(fl)puts("Impossible");
    103     else printf("%lld",ans);
    104     return 0;
    105 }
  • 相关阅读:
    线性回归损失函数求解
    【线性代数】四个基本子空间
    【线性代数】如何寻找一个投影矩阵
    【hihoCoder】#1133 : 二分·二分查找之k小数
    [LeetCode解题报告] 502. IPO
    [LeetCode解题报告] 703. 数据流中的第K大元素
    【排序】堆排序
    全文检索以及Lucene的应用
    MySql优化之mycat
    MySql优化之主从复制
  • 原文地址:https://www.cnblogs.com/Qin-Wei-Kai/p/10104831.html
Copyright © 2011-2022 走看看