您的位置:首页 > 其它

NOIP2009 细胞分裂

2012-03-18 18:13 113 查看
题意抽象出来就是求(cell[i])^k mod m1^m2=0的最小的k值。

把m1^m2分解质因数即可,再把每一个细胞数分解,对比其质因子数量,对于某个因子,m1^m2次有而后者没有,那么这种情况一定无解,继续枚举下一个细胞数即可,而两者都有时,就是要最少的后者的因子凑出大于等于后者因子的最小次幂,处理完每一个因子后取因子需要的最大值,用它去更新答案。

注意m1=1时的特殊情况。

View Code

program tyvj1105(input,output);
var
v        : array[2..50000] of boolean;
prime    : array[1..6000] of longint;
goal        : array[1..6000] of longint;
now        : array[1..6000] of longint;
cell        : array[1..10001] of longint;
m1,m2    : longint;
n,primes : longint;
answer   : longint;
procedure previous;
var
i,j : longint;
begin
primes:=0;
fillchar(v,sizeof(v),false);
for i:=2 to 50000 do
if not v[i] then
begin
inc(primes);
prime[primes]:=i;
j:=i+i;
while j<=50000 do
begin
v[j]:=true;
j:=j+i;
end;
end;
end; { previous }
procedure init;
var
i : longint;
begin
readln(n);
readln(m1,m2);
for i:=1 to n do
read(cell[i]);
end; { init }
procedure Decomposition(x: longint );
var
tmp : longint;
i   : longint;
begin
tmp:=(x+1)>>1;
fillchar(now,sizeof(now),0);
for i:=1 to primes do
if prime[i]>tmp then
exit
else
while (x mod prime[i]=0) do
begin
inc(now[i]);
x:=x div prime[i];
end;
end; { Decomposition }
procedure make(x : longint );
var
i : longint;
begin
fillchar(goal,sizeof(goal),0);
for i:=1 to primes do
while (x mod prime[i]=0) do
begin
inc(goal[i]);
x:=x div prime[i];
end;
end; { make }
procedure main;
var
i,j         : longint;
flag         : boolean;
max         : longint;
begin
answer:=maxlongint>>1;
make(m1);
for i:=1 to primes do
goal[i]:=goal[i]*m2;
for i:=1 to n do
begin
max:=0;
flag:=true;
Decomposition(cell[i]);
for j:=1 to primes do
if (goal[j]<>0)and(now[j]=0) then
begin
flag:=false;
break;
end
else
if goal[j]<>0 then
begin
if (goal[j] mod now[j]=0) then
begin
if goal[j] div now[j]>max then
max:=goal[j] div now[j];
end
else
if (goal[j] div now[j])+1>max then
max:=(goal[j] div now[j])+1;
end
else
continue;
if not flag then
continue
else
if (max<answer)and(max<>0) then
answer:=max;
end;
end; { main }
procedure print;
begin
if answer=maxlongint>>1 then
writeln(-1)
else
writeln(answer);
end; { print }
begin
previous;
init;
if m1=1 then
writeln(0)
else
begin
main;
print;
end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: