zoukankan      html  css  js  c++  java
  • 【BZOJ2142】礼物(扩展lucas定理,中国剩余定理合并方程)

    题意:有n件礼物,m个人,每个人分别需要w[i]件礼物,求分礼物的不同方案数 mod P

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

    1≤n≤10^9,1≤m≤5,1≤pi^ci≤10^5。

    P不一定为质数

    思路:经推导答案即为n!/(w[i]!),i=1..n

    考虑P不是质数

    将P分解为提示中所说的形式,可以发现所有pt^ct都是互质的,所以我们可以用下图的中国剩余定理合并

    From http://blog.csdn.net/popoqqq/article/details/39891263

    然后对于每个pi^ai,我们进行以下处理:

    将分子和分母化为x*pi^y的形式

    然后分母的x部分与pi互质,可以求逆元,分子分母的y部分直接相减即可

    然后我们处理阶乘

    以19为例,将19!化为x*pi^y的形式,其中pi=3,ai=2 则有

    19!%9=(1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19) %9

               =(1*2*4*5*7*8*10*11*13*14*16*17*19)*3^6*(1*2*3*4*5*6) %9

    式子的左半部分是不为3的倍数的数,存在长度为p^a的循环节 求出一个循环节 快速幂处理 然后处理剩余部分

    右半部分是6!%9 递归处理即可

    用这样的思路就可以换解决C(n,m) mod p,p不为质数的情况了

      1 var a:array[1..1000]of int64;
      2     n,m,i:longint;
      3     ans,s,mo:int64;
      4 
      5 function mult(x,y,p:int64):int64;
      6 var tmp:int64;
      7 begin
      8  mult:=1; tmp:=x;
      9  while y>0 do
     10  begin
     11   if y and 1=1 then mult:=mult*tmp mod p;
     12   tmp:=tmp*tmp mod p;
     13   y:=y>>1;
     14  end;
     15 end;
     16 
     17 procedure exgcd(a,b:int64;var d,x,y:int64);
     18 begin
     19  if b=0 then
     20  begin
     21   d:=a; x:=1; y:=0;
     22  end
     23   else
     24   begin
     25    exgcd(b,a mod b,d,y,x);
     26    y:=y-(a div b)*x;
     27   end;
     28 end;
     29 
     30 function inv(a,n:int64):int64;
     31 var d,x,y:int64;
     32 begin
     33  exgcd(a,n,d,x,y);
     34  if d=1 then exit((x+n) mod n);
     35  exit(-1);
     36 end;
     37 
     38 function fac(n,p,pr:int64):int64;
     39 var i,re,r:int64;
     40 begin
     41  if n=0 then exit(1);
     42  re:=1; i:=2;
     43  while i<=pr do
     44  begin
     45   if i mod p>0 then re:=re*i mod pr;
     46   inc(i);
     47  end;
     48 
     49  re:=mult(re,n div pr,pr);
     50  r:=n mod pr;
     51  i:=2;
     52  while i<=r do
     53  begin
     54   if i mod p>0 then re:=re*i mod pr;
     55   inc(i);
     56  end;
     57 
     58  exit(re*fac(n div p,p,pr) mod pr);
     59 end;
     60 
     61 function c(n,m,p,pr:int64):int64;
     62 var x,y,z,t,tmp:int64;
     63 begin
     64  if n<m then exit(0);
     65  x:=fac(n,p,pr);
     66  y:=fac(m,p,pr);
     67  z:=fac(n-m,p,pr);
     68  c:=0;
     69  t:=n;
     70  while t>0 do
     71  begin
     72   c:=c+t div p;
     73   t:=t div p;
     74  end;
     75  t:=m;
     76  while t>0 do
     77  begin
     78   c:=c-t div p;
     79   t:=t div p;
     80  end;
     81  t:=n-m;
     82  while t>0 do
     83  begin
     84   c:=c-t div p;
     85   t:=t div p;
     86  end;
     87  tmp:=x*inv(y,pr) mod pr*inv(z,pr) mod pr*mult(p,c,pr) mod pr;
     88  exit(tmp*(mo div pr) mod mo*inv(mo div pr,pr) mod mo);
     89 end;
     90 
     91 
     92 function lucas(n,m:int64):int64;
     93 var x,re,i,pr:int64;
     94 begin
     95  i:=2; x:=mo; re:=0;
     96  while i<=x do
     97  begin
     98   if x mod i=0 then
     99   begin
    100    pr:=1;
    101    while x mod i=0 do
    102    begin
    103     x:=x div i; pr:=pr*i;
    104    end;
    105    re:=(re+c(n,m,i,pr)) mod mo;
    106   end;
    107   inc(i);
    108  end;
    109  exit(re);
    110 end;
    111 
    112 begin
    113  assign(input,'bzoj2142.in'); reset(input);
    114  assign(output,'bzoj2142.out'); rewrite(output);
    115  readln(mo);
    116  readln(n,m);
    117  for i:=1 to m do
    118  begin
    119   read(a[i]); s:=s+a[i];
    120  end;
    121  if s>n then
    122  begin
    123   writeln('Impossible');
    124   close(input);
    125   close(output);
    126   exit;
    127  end;
    128  ans:=1;
    129  for i:=1 to m do
    130  begin
    131   ans:=ans*lucas(n,a[i]) mod mo;
    132   n:=n-a[i];
    133  end;
    134  writeln(ans);
    135 
    136  close(input);
    137  close(output);
    138 end.
  • 相关阅读:
    线性参考
    unix下安装Server(静默方式)
    ArcGIS Server REST开发模式
    Python中调用AO
    Oracle 冷备份
    平头缓冲
    Oracle 热备份
    Socket获取远程连接者的IP
    c#调用cmd执行相关命令
    C#_winform_DataGridView_的18种常见属性 (转)
  • 原文地址:https://www.cnblogs.com/myx12345/p/7157735.html
Copyright © 2011-2022 走看看