您的位置:首页 > 其它

【NOIP2013模拟联考3】恭介的法则(rule) (Standard IO)

2017-08-18 16:15 351 查看

题目大意:

假设第一个毒气罐被打开的概率为1/x,第二个毒气罐为1/y(x,y 为正整数),那么当两个概率和为1/(n!)时,猫将会被莫名其妙地杀死。现在美鱼想知道,有多少对(x,y)可以让猫被莫名其妙杀死。其实就是求满足1/x+1/y=1/n!的x,y的正整数对数
n<700000


思路:

很难,很难。我也不会。。。。。。。。。。。。。。。。。。。。。。。。。
额
额
额
额
额
额
额
额
额
额
额
额

额
额
额
额
额
额

额
额
额
额
额
额

额
额
额
额
额
额

额
额
额
额
额
额

额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额          额
额
额
额
额
额
还是讲讲吧,第一呢,要会nlogn以上的筛素数方法,然后知道如何求一个数的因数有多少个。公式百度,或者看我程序。
然后说说。设 m=n! ,由等式知x,y必定大于n!,所以再设 x=n!+k=m+k 带入 1/m=1/x+1/y 中化简得到y=m*m/k+m,因y为整数,所以要求k整除m*m,即k为m*m的因子,问题便转化为求n!*n!的因子个数, 设n!=p1^e1 * p2^e2 * p3^e3 *...*pk^ek,则 n!*n!= p1^(2*e1) * p2^(2*e2) *...*pk^(2*ek) 。 则因子个数sum=(2*e1+1)*(2*e2+1)*...*(2*ek+1)。所以就可以求出来满足的个数了


const
maxn=700000;
maxv=6000;
mo=1000000000;
var
a,b:array [1..maxn] of longint;
ans:array [1..maxv] of int64;
i,j,n,m,k,o,p,s:longint;
flag:array [1..maxn] of boolean;
xx:int64;
procedure mul(y:longint);
var
i,j:longint;
x:int64;
begin
x:=0;
for i:=maxv downto s-2 do
begin
ans[i]:=ans[i]*y+x;
x:=ans[i] div mo;
ans[i]:=ans[i] mod mo;
end;
while ans[s-1]<>0 do dec(s);
end;

begin
s:=maxv;
fillchar(ans,sizeof(ans),0);
readln(n);
for i:=2 to n do
if not flag[i] then
begin
for j:=1 to n div i do

4000
begin
flag[i*j]:=true;
o:=i*j;
k:=0;
while (o mod i=0) and (o<>0) do
begin
o:=o div i;
inc(k);
end;
inc(a[i],k);
end;
end;
for i:=1 to maxn do
a[i]:=a[i]*2;
ans[maxv]:=1;
for i:=1 to maxn do
if a[i]<>0 then
begin
inc(p);
b[p]:=a[i];
end;
xx:=1;
for i:=p downto 1 do
begin
if xx*(b[i]+1)<mo then xx:=xx*(b[i]+1)
else
begin
mul(xx);
xx:=b[i]+1;
end;
end;
mul(xx);
j:=1;
while ans[j]=0 do inc(j);
write(ans[j]);
for i:=j+1 to maxv do
begin
if ans[i]<100000000 then write('0');
if ans[i]<10000000 then write('0');
if ans[i]<1000000 then write('0');
if ans[i]<100000 then write('0');
if ans[i]<10000 then write('0');
if ans[i]<1000 then write('0');
if ans[i]<100 then write('0');
if ans[i]<10 then write('0');
write(ans[i]);
end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  何嘉阳