昂贵的珍珠垂饰

来源:互联网 发布:手机汇编软件 编辑:程序博客网 时间:2024/04/28 23:02

题目

情人节之际,Alex决定用K种珍珠为他的GF做一串举世无双的珍珠垂饰与她的项链相配。珍珠垂饰是由珍珠连接而成的,其长度可以认为就是珍珠垂饰上珍珠的个数。众所周知,Alex家缠万贯,每种珍珠他都拥有N颗。根据将珍珠垂饰打开后珍珠不同的排列顺序可以区别不同种类的项链。现在,他好奇自己可以组成多少种长度为1至N的不同的珍珠垂饰?当然,为显富有,每串珍珠垂饰都要必须由K种珍珠连成。

答案取模1234567891。
1 <= T <= 10
1 <= N <= 1,000,000,000
1 <= K <= 30

分析

容斥原理
先枚举一个n表示长度,那么方案数便是:
knC(k,1)(k1)n+C(k,2)(k2)nC(k,3)(k3)n.....
nk+(1)iC(k,i)(ki)n
然而n太大了,我们不能这样枚举n来做,
故我们试着列出每个n的长度的式子:
knC(k,1)(k1)n+C(k,2)(k2)nC(k,3)(k3)n.....
kn1C(k,1)(k1)n1+C(k,2)(k2)n1C(k,3)(k3)n1.....
kn2C(k,1)(k1)n2+C(k,2)(k2)n2C(k,3)(k3)n2.....
然后我们把每个式子的每一项拿出来,便会发现这是等比数列!
于是我们便可以用等比数列求和公式很好的解决问题了。

等比数列求和

那么我们便来讲一讲等比数列求和的方法:
ai,iq
s=a1+a2+a3...an
那么qs=a1q+a2q...anq=a2+a3+a4....+an+1
接着我们再把它们相减:
(q1)s=an+1a1
s=an+1a1q1
到此便很好得解决问题了。

代码

const mo=1234567891;var    t,i,j,n,m,s:longint;    fm,an,a1,q,ans:int64;    c:array[0..31,0..31] of int64;function msort(x,y:longint):int64;begin     if y=1 then exit(x)     else begin          msort:=msort(x,y div 2);          msort:=(msort*msort)mod mo;          if y mod 2<>0 then msort:=(msort*x)mod mo;     end;end;begin    readln(t);    c[0,0]:=1;    for i:=1 to 31 do        for j:=1 to i do            c[i,j]:=c[i-1,j-1]+c[i-1,j];    for t:=1 to t do begin         readln(n,m);         ans:=0;s:=1;         if m=1 then ans:=n         else         for i:=m downto 1  do begin             q:=i;             an:=msort(q,n);             a1:=q;             if q=1 then begin                fm:=1;                ans:=(ans+s*n*c[m+1,m-i+1])mod mo;s:=s*(-1);             end             else begin             fm:=msort(q-1,mo-2);             ans:=(((c[m+1,m-i+1]*(((((an*q)mod mo)-a1+mo)*fm)mod mo))mod mo)*s+ans)mod mo;s:=s*(-1);             end;         end;         writeln((ans+mo)mod mo);    end;end.
0 0
原创粉丝点击