方程的解_NOI导刊2010提高

题目描述 Description
佳佳碰到了一个难题,请你来帮忙解决。
    对于不定方程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
输入样例:
3 2
输出样例:
3
 说明 description
对于40%的数据,ans≤10^16;对于100%的数据,k≤100,x≤2^31-1,k≤g(x)。
NOI导刊2010提高

t=x^x=g[x]
a1+a2+a3+...+ak=t
插空法 ans=c(k-1,t-1)
ans=(t-1)!/((t-k)!(k-1)!)
=(t-1)*(t-2)*...*(t-k+1)/(k-1)!
先用高精乘求出分子,再用高精除单精得到结果{结果一定为整数}

var x:longint;
ans,k:longint;
ii,i,j,xx,l,len:longint;
temp:array[0..1000]of longint;
init1,init2,init3:array[0..10000]of integer;
a,b,c,d:longint;
begin 
readln(k,x);
i:=x;
while i>0 do
begin inc(temp[0]);
temp[temp[0]]:=i mod 2;
if i mod 2=1
then i:=(i-1) div 2
else i:=i div 2;
end;
xx:=1;
for i:=temp[0] downto 1 do
if temp[i]=1
then xx:=(((xx mod 1000)*(xx mod 1000)) mod 1000)*(x mod 1000) mod 1000
else xx:=((xx mod 1000)*(xx mod 1000)) mod 1000;
      fillchar(init1,sizeof(init1),0);
fillchar(init2,sizeof(init2),0);
fillchar(init3,sizeof(init3),0);
a:=xx-1;
b:=xx-k;
c:=k-1;
      init1[0]:=1; init1[1]:=1;
init2[0]:=1; init2[1]:=1;
init3[0]:=1; init3[1]:=1;
for i:=b+1 to a do
begin for j:=1 to init1[0] do
init1[j]:=init1[j]*i;
l:=init1[0]+5;
for j:=1 to l do
begin init1[j+1]:=init1[j+1]+init1[j] div 10;
init1[j]:=init1[j] mod 10;
end;
while init1[l]=0 do dec(l);
init1[0]:=l;
end;
d:=0;
for ii:=c downto 2 do
begin for i:=init1[0] downto 1 do
begin d:=d*10+init1[i];
init1[i]:=d div ii;
d:=d mod ii;
end;
l:=init1[0];
while init1[l]=0 do dec(l);
init1[0]:=l;
end;
for i:=init1[0] downto 1 do
write(init1[i]);
end.
原文地址:https://www.cnblogs.com/spiderKK/p/4886478.html