题目
情人节之际,Alex决定用K种珍珠为他的GF做一串举世无双的珍珠垂饰与她的项链相配。珍珠垂饰是由珍珠连接而成的,其长度可以认为就是珍珠垂饰上珍珠的个数。众所周知,Alex家缠万贯,每种珍珠他都拥有N颗。根据将珍珠垂饰打开后珍珠不同的排列顺序可以区别不同种类的项链。现在,他好奇自己可以组成多少种长度为1至N的不同的珍珠垂饰?当然,为显富有,每串珍珠垂饰都要必须由K种珍珠连成。
答案取模1234567891。
1 <= T <= 10
1 <= N <= 1,000,000,000
1 <= K <= 30
分析
容斥原理
先枚举一个n表示长度,那么方案数便是:
kn−C(k,1)∗(k−1)n+C(k,2)∗(k−2)n−C(k,3)∗(k−3)n.....
即
nk+∑(−1)i∗C(k,i)∗(k−i)n
然而n太大了,我们不能这样枚举n来做,
故我们试着列出每个n的长度的式子:
kn−C(k,1)∗(k−1)n+C(k,2)∗(k−2)n−C(k,3)∗(k−3)n.....
kn−1−C(k,1)∗(k−1)n−1+C(k,2)∗(k−2)n−1−C(k,3)∗(k−3)n−1.....
kn−2−C(k,1)∗(k−1)n−2+C(k,2)∗(k−2)n−2−C(k,3)∗(k−3)n−2.....
然后我们把每个式子的每一项拿出来,便会发现这是等比数列!
于是我们便可以用等比数列求和公式很好的解决问题了。
等比数列求和
那么我们便来讲一讲等比数列求和的方法:
ai,表示等比数列中第i项,q表示公比
设
s=a1+a2+a3...an
,
那么
qs=a1∗q+a2∗q...an∗q=a2+a3+a4....+an+1
接着我们再把它们相减:
(q−1)s=an+1−a1
故
s=an+1−a1q−1
到此便很好得解决问题了。
代码
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.