题目描述
佳佳碰到了一个难题,请你来帮忙解决。
对于不定方程a1+a2+…+ak-1+ak=g(x),其中k≥2且k∈N,x是正整数,g(x)=x^x mod 1000(即x^x除以1000的余数),x,k是给定的数。我们要求的是这个不定方程的正整数解组数。
举例来说,当k=3,x=2时,分别为(a1,a2,a3)=(2,1,1)’(1,2,1),(1,1,2)。
输入输出格式 Input/output
输入格式:
输入文件equation.in有且只有一行,为用空格隔开的两个正整数,依次为k,x。
输出格式:
输出文件equation.out有且只有一行,为方程的正整数解组数。
输入输出样例 Sample input/output
样例测试点#1 输入样例: 在线IDE
输出样例:
说明 description
对于40%的数据,ans≤10^16;对于100%的数据,k≤100,x≤2^31-1,k≤g(x)。
思路
组合数学+高精
先用快速幂算出n:=g(x),然后把他们看做g(x)个1,因为要把它们组合成k个数,n-1个空,需要选择k-1个空,根据插空法原理,结果为
=【(n-1)!】/ 【(k-1)! (n-k)!】
=【(n-1)(n-2)……(n-k+1)】/(k-1)!
不要傻傻的高精乘单精和高精除高精,仅仅是先用高精乘单精算出分子,然后再高精除以每个分母
代码
var i,len,x,k,n:longint;
num2,num1:array[1..10000]of longint;
procedure mi(a,b,c:longint);
begin
n:=1;
a:=a mod c;
while b>0 do
begin
if (b and 1)=1 then n:=(n*a) mod c;
b:=b shr 1;
a:=(a*a)mod c;
end;
end;
procedure cheng(n:longint);
var i:longint;
begin
for i:=1 to len do num1[i]:=num1[i]*n;
for i:=1 to len do
begin
num1[i+1]:=num1[i+1]+num1[i] div 10;
num1[i]:=num1[i] mod 10;
end;
while num1[len+1]>0 do
begin
inc(len);
num1[len+1]:=num1[len+1]+num1[len] div 10;
num1[len]:=num1[len] mod 10;
end;
end;
procedure chu(n:longint);
var d,i:longint;
begin
fillchar(num2,sizeof(num2),0);
d:=0;
for i:=len downto 1 do
begin
d:=d*10+num1[i];
num2[i]:=d div n;
d:=d mod n;
end;
while num2[len]=0 do dec(len);
for i:=1 to len do num1[i]:=num2[i];
end;
begin
readln(k,x);
mi(x,x,1000);
num1[1]:=1;
len:=1;
for i:=n-k+1 to n-1 do cheng(i);
for i:=2 to k-1 do chu(i);
for i:=len downto 1 do write(num1[i]);
end.
评测结果:Accepted
得分: 100
提交时间:2015-10-17 16:59 耗时:91ms
内存:3182kb 点击进入记录列表。
编译信息 Compiling
编译成功
评测结果 Result
测试点 #1:通过该测试点。 得分10,耗时0ms,内存3162kB。
测试点 #2:通过该测试点。 得分10,耗时0ms,内存3174kB。
测试点 #3:通过该测试点。 得分10,耗时0ms,内存3178kB。
测试点 #4:通过该测试点。 得分10,耗时15ms,内存3178kB。
测试点 #5:通过该测试点。 得分10,耗时15ms,内存3178kB。
测试点 #6:通过该测试点。 得分10,耗时0ms,内存3178kB。
测试点 #7:通过该测试点。 得分10,耗时31ms,内存3178kB。
测试点 #8:通过该测试点。 得分10,耗时0ms,内存3182kB。
测试点 #9:通过该测试点。 得分10,耗时15ms,内存3182kB。
测试点 #10:通过该测试点。 得分10,耗时15ms,内存3178kB。