问题转化成求C(N,M) mod P p为非素数,那么我们可以将P分解质因数,

也就是 π pi^ci的形式,因为这些pi^ci是互质的,所以我们可以用crt将他们合并

那么问题就转化成了快速求C(N,M) mod pi^ci

那么我们看下c的形式,为N!/(M!(N-M)!) mod pi^ci

因为mod的数不是质数,所以分母没法正常求逆元,那么我们可以将分子分母

中的pi的值挑出,那么我们先求N!,可以发现,N!mod pi^ci可以分段,每段是

pi^ci长,这一段的值是0--(pi^ci-1),那么因为我们需要将N!中pi|I的挑出来

剩下一些数,那就是好几段这个数相乘,用快速幂解决就行了,设cnt为p!其中

不包括pi|n的

那么N! mod pi^ci就变成了cnt^x*pi^y,那么x,y我们可以求出来,然后div掉p

之后,就又出现了一个阶乘,那么递归去做就行了。

比如N=11 pi=2 ci=2

N!为1*2*3*4*5*6*7*8*9*10*11

那么就是[1*3]*[5*7]*[9*11] mod pi^ci

挑出来的数是2,4,6,8,10,都div pi之后是

1,2,3,4,5 然后就成一个子问题了。

/**************************************************************
    Problem:
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time: ms
    Memory: kb
****************************************************************/
 
//By BLADEVIL
var
    m, n                                :longint;
    pj, c                               :array[..] of longint;
    pi, s, a                            :array[..] of int64;
    p                                   :int64;
    tot                                 :longint;
  
procedure divide(p:int64);
var   
    i, j                                :longint;
      
begin
    tot:=;
    for i:= to trunc(sqrt(p)) do
    if p mod i= then
    begin
        inc(tot);
        pj[tot]:=i;
        while p mod i= do
        begin
                inc(c[tot]);
                p:=p div i;
        end;
    end;
    if p> then
    begin
        inc(tot);
        pj[tot]:=p;
        c[tot]:=;
    end;
    for i:= to tot do
    begin
        pi[i]:=;
        for j:= to c[i] do pi[i]:=pi[i]*pj[i];
    end;
end;
  
function ex_gcd(a,b:int64;var x,y:int64):int64;
var   
    t                                   :int64;
begin
    if (b=) then
    begin
        x:=;y:=;
        exit(a);
    end;
    ex_gcd:=ex_gcd(b,a mod b,x,y);
    t:=x;
    x:=y;
    y:=t-(a div b)*y;
end;
  
function gcd(a,p:int64):int64;
var   
    x, y                                :int64;
      
begin
    x:=;y:=;
    ex_gcd(a,p,x,y);
    x:=(x mod p+p)mod p;
    exit(x);
end;
  
function mi(x,y,q:int64):int64;
var
    rec                                 :int64;
      
begin
    rec:=;
    while (y>) do
    begin
        if y and = then rec:=rec*x mod q;
        x:=x*x mod q;
        y:=y shr ;
    end;
    exit(rec);
end;
  
function fac(n,p,q:int64):int64;
var
    cnt                                 :int64;
    i                                   :longint;
begin
    cnt:=;
    for i:= to n do
        if (i mod p>) then
            cnt:=cnt*i mod q;
    exit(cnt);
end;
  
function fact(n:int64;var sum:int64;p,q:int64):int64;
var
    cnt, rec                            :int64;
      
begin
    rec:=;
    cnt:=fac(q,p,q);
    while n>=p do
    begin
        sum:=sum+n div p;
        if (n div q>) then rec:=rec*(mi(cnt,n div q,q) mod q)mod q;
        if (n mod q>) then rec:=rec*(fac(n mod q,p,q)mod q) mod q;
        n:=n div p;
    end;
    if n> then rec:=rec*fac(n,p,q) mod q;
    exit(rec);
end;
  
function combine(n,m,p,q:int64):int64;
var   
    ans1, ans2, ans3, ans               :int64;
    a, b, c                             :int64;
      
begin
    a:=;b:=;c:=;
    ans1:=fact(n,a,p,q);
    ans2:=fact(m,b,p,q);
    ans3:=fact(n-m,c,p,q);
    a:=a-(b+c);
    ans:=mi(p,a,q);
    ans:=ans*ans1 mod q;
    ans:=ans*gcd(ans2,q) mod q;
    ans:=ans*gcd(ans3,q) mod q;
    exit(ans);
end;
  
function doit(n,m:longint):int64;
var
    i                                   :longint;
    x, y, sum                           :int64;
          
begin
    sum:=;
    for i:= to tot do
            a[i]:=combine(n,m,pj[i],pi[i]);
    for i:= to tot do
    begin
        x:=;y:=;
        ex_gcd(s[i],pi[i],x,y);
        x:=(x mod pi[i]+pi[i])mod pi[i];
        sum:=(sum+((x*s[i] mod p)*a[i])mod p)mod p;
    end;
    exit(sum mod p);
end;
  
procedure main;
var   
    i                                   :longint;
    w                                   :array[..] of longint;
    ans                                 :int64;
    sum                                 :int64;
      
begin
    readln(p);
    divide(p);
    for i:= to tot do s[i]:=p div pi[i];
    readln(n,m);
    sum:=;
    for i:= to m do
    begin
        readln(w[i]);
        inc(sum,w[i]);
    end;
    if sum>n then
    begin
        writeln('Impossible');
        exit;
    end;
    ans:=;
    for i:= to m do
    begin
        ans:=ans*doit(n,w[i]) mod p;
        n:=n-w[i];
    end;
    writeln(ans);
end;
  
begin
    main;
end.

bzoj 2142 国家集训队试题 礼物的更多相关文章

  1. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

  2. BZOJ.2565.[国家集训队]最长双回文串(Manacher/回文树)

    BZOJ 洛谷 求给定串的最长双回文串. \(n\leq10^5\). Manacher: 记\(R_i\)表示以\(i\)位置为结尾的最长回文串长度,\(L_i\)表示以\(i\)开头的最长回文串长 ...

  3. BZOJ 2631 [国家集训队]Tree II (LCT)

    题目大意:给你一棵树,让你维护一个数据结构,支持 边的断,连 树链上所有点点权加上某个值 树链上所有点点权乘上某个值 求树链所有点点权和 (辣鸡bzoj又是土豪题,洛谷P1501传送门) LCT裸题, ...

  4. 洛谷 P1505 BZOJ 2157 [国家集训队]旅游

    bzoj题面 Time limit 10000 ms Memory limit 265216 kB OS Linux 吐槽 又浪费一个下午--区间乘-1之后,最大值和最小值更新有坑.新的最大值是原来最 ...

  5. Bzoj 2038---[2009国家集训队]小Z的袜子(hose) 莫队算法

    题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=2038 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色 ...

  6. Bzoj2034 2009国家集训队试题 最大收益 贪心+各种优化+二分图

    这个题真的是太神了... 从一開始枚举到最后n方的转化,各种优化基本都用到了极致.... FQW的题解写了好多,个人感觉我全然没有在这里废话的必要了 直接看这里 各种方法真的是应有尽有 大概说下 首先 ...

  7. Luogu P1852 BZOJ 2144 [国家集训队]跳跳棋

    qwq 这题一看就不会,如果不是gg让做我是坚决不会做的 画图模拟,因为一次只能跳过一个棋子,所以对于一种情况只有三种移动方式: 中间向左跳 中间向右跳 左或右(距中间近的那个)向中间跳 发现,除了跳 ...

  8. BZOJ.2134.[国家集训队]单选错位(概率 递推)

    题目链接 如题目中的公式,我们只要把做对每个题的概率加起来就可以了(乘个1就是期望). 做对第i道题的概率 \[P_i=\frac{1}{max(a_{i-1},a_i)}\] 原式是 \(P_i=\ ...

  9. Luogu2183【国家集训队】礼物

    题面 题解 易得答案为 $$ \sum_{i=1}^m\binom{n-\sum_{j=1}^{i-1}w_j}{\sum_{j=1}^iw_j} $$ 扩展$\text{Lucas}$即可 代码 # ...

随机推荐

  1. js学习日记-常用正则符号参考

    预定义类 量词 贪婪.惰性.支配性量词 前瞻 边界 RegExp是全局对象,RegExp.$1...$9是全局属性.当执行任意正则表达式匹配操作时,JavaScript会自动更新全局对象RegExp上 ...

  2. Linux开发C语言规范

    -Iinclude:找头文件目录 ,获取头文件的目录 -C:创建.o文件 .h:文件用来声明函数,即写一个函数名. 如 int add(); int div(); int mul(); .c:文件定义 ...

  3. Python目录链接

    第1章 就这么愉快的开始吧 课时1:我和python的第一次亲密接触 一.Python3的下载与安装 二.从IDIE启动Python 三.尝试点新的东西 四.为什么会这样? 五.课时01课后习题及答案 ...

  4. HDU 4735 Little Wish~ lyrical step~(DLX搜索)(2013 ACM/ICPC Asia Regional Chengdu Online)

    Description N children are living in a tree with exactly N nodes, on each node there lies either a b ...

  5. 阿里云服务器 linux下载 jdk

    直接从本地下载包上传比较慢.直接在服务器上下载安装包: 1.进入orcle官网; 2.选择需要下载的版本,下载需要同意orcle协议, 3.点击下载,获取到下载请求的cookie, 复制所有cooki ...

  6. PAT 甲级 1015 Reversible Primes

    https://pintia.cn/problem-sets/994805342720868352/problems/994805495863296000 A reversible prime in ...

  7. 使用JSON数据格式模拟股票实时信息

    JQueryStock.html <!DOCTYPE html> <head> <meta charset="UTF-8"> <title ...

  8. 51nod 1967路径定向(欧拉回路)

    题目大意:给出一个图,安排边的方向,使得入度等于出度的点数最多,并给出方案. 首先假设是个无向图,不妨认定偶点必定可以满足条件 我们还会发现,奇点的个数必定是偶数个 那么如果把奇点两两用辅助边连起来, ...

  9. 【题解】SDOI2010地精部落

    强!强!强!强!劲啊劲啊劲啊!!!洛谷P2467 非常重要的,就在于发现以下的两条性质: 1.当i与i+1不相邻时,方案数是一样的:交换这两个数,<i+1的必然<i,>i+1的必然& ...

  10. [洛谷P4779]【模板】单源最短路径(标准版)

    题目大意:单元最短路径(卡$SPFA$) 题解:$dijkstra$($\underline{\hspace{0.5em}}\underline{\hspace{0.5em}}gnu\underlin ...