Tyvj 1231 跳格子I (数学,欧拉函数)(高精度)

P1231 跳格子I
时间: 1000ms / 空间: 131072KiB / Java类名: Main

背景
tyvj20100613比赛,祝大家取得好成绩。^-^

描述
小msh喜欢玩一种跳格子的沙茶游戏。在地上画一个n*m的方格,她每次可以从一个格子跳到与它相邻的另一个格子中(相邻的两个格子有且仅有一条公共边)。小msh想从最左上角的格子跳到最右下角的格子中,但她不想一直跳一直跳(比如先向右,再向左,再向右,再向左……这样跳个没完,像沙茶一样……),所以她想用尽量少的步数跳完。但是这样的跳法似乎有很多种……那么你来计算一下一共有多少种跳法吧!

输入格式
一行,两个整数n和m,表示方格的行数和列数。

输出格式
一行,一个数T,表示跳法的总数。

测试样例1
输入
2 3
输出
3

备注
对于30%的数据,1<=n,m<=30;
对于70%的数据,1<=n,m<=200;
对于100%的数据,1<=n,m<=10000.

咳咳,这一题之前的模拟赛做过比较类似的一题叫数学作业,画一画数据发现这个表格其实是一个杨辉三角,那么题目就转变成了求C(m,n)的问题(m在题中对应m+n-2,n对应n-1)。 那么求C(m,n)的公式肯定都了解,主要是这题数据到了一万,无法直接枚举,显然是要有一点技巧咯。 那么我们可以先用for循环枚举到每一个数的算术平方根,记录C(m,n)之内含有的质因子的个数(分数线上面的要inc,下面的要dec,最后统计正数的部分),在运用欧拉函数求解即可(需要使用高精度)

program mys;

var m,n,p,i,j,k,x,len,y:longint;
s:string;
f,a,b:array[0..500000]of longint;

procedure fa;
var i,j:longint;
begin 
for i:=1 to m+n do
while f[i]>0 do
begin
for j:=1 to len do
a[j]:=a[j]*i;
for j:=1 to 10000 do
begin
a[j+1]:=a[j+1]+a[j] div 10;
a[j]:=a[j] mod 10;
end;
j:=10000;
while a[j]=0 do dec(j);
len:=j;
dec(f[i]);
end;
end;

begin 
readln(m,n);
if (m=1)and(n=1) then 
begin writeln(1); halt; end;

dec(m); dec(n);
n:=n+m;
for i:=m+1 to n do 
begin 
x:=i;
for j:=2 to trunc(sqrt(i)) do
begin 
while x mod j=0 do 
begin 
inc(f[j]);
x:=x div j;
end;
end;
if x>1 then inc(f[x]);
end;

for i:=1 to n-m do 
begin 
x:=i;
for j:=2 to trunc(sqrt(i)) do 
begin 
while x mod j=0 do 
begin 
dec(f[j]);
x:=x div j;
end;
end;
if x>1 then dec(f[x]);
end;

a[1]:=1; len:=1;
fa;
for i:=len downto 1 do
write(a[i]);
end.

你可能感兴趣的:(数学,高精度)