NOIP2009 细胞分裂

题意抽象出来就是求(cell[i])^k mod m1^m2=0的最小的k值。

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

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

View Code
  1 program tyvj1105(input,output);
2 var
3 v : array[2..50000] of boolean;
4 prime : array[1..6000] of longint;
5 goal : array[1..6000] of longint;
6 now : array[1..6000] of longint;
7 cell : array[1..10001] of longint;
8 m1,m2 : longint;
9 n,primes : longint;
10 answer : longint;
11 procedure previous;
12 var
13 i,j : longint;
14 begin
15 primes:=0;
16 fillchar(v,sizeof(v),false);
17 for i:=2 to 50000 do
18 if not v[i] then
19 begin
20 inc(primes);
21 prime[primes]:=i;
22 j:=i+i;
23 while j<=50000 do
24 begin
25 v[j]:=true;
26 j:=j+i;
27 end;
28 end;
29 end; { previous }
30 procedure init;
31 var
32 i : longint;
33 begin
34 readln(n);
35 readln(m1,m2);
36 for i:=1 to n do
37 read(cell[i]);
38 end; { init }
39 procedure Decomposition(x: longint );
40 var
41 tmp : longint;
42 i : longint;
43 begin
44 tmp:=(x+1)>>1;
45 fillchar(now,sizeof(now),0);
46 for i:=1 to primes do
47 if prime[i]>tmp then
48 exit
49 else
50 while (x mod prime[i]=0) do
51 begin
52 inc(now[i]);
53 x:=x div prime[i];
54 end;
55 end; { Decomposition }
56 procedure make(x : longint );
57 var
58 i : longint;
59 begin
60 fillchar(goal,sizeof(goal),0);
61 for i:=1 to primes do
62 while (x mod prime[i]=0) do
63 begin
64 inc(goal[i]);
65 x:=x div prime[i];
66 end;
67 end; { make }
68 procedure main;
69 var
70 i,j : longint;
71 flag : boolean;
72 max : longint;
73 begin
74 answer:=maxlongint>>1;
75 make(m1);
76 for i:=1 to primes do
77 goal[i]:=goal[i]*m2;
78 for i:=1 to n do
79 begin
80 max:=0;
81 flag:=true;
82 Decomposition(cell[i]);
83 for j:=1 to primes do
84 if (goal[j]<>0)and(now[j]=0) then
85 begin
86 flag:=false;
87 break;
88 end
89 else
90 if goal[j]<>0 then
91 begin
92 if (goal[j] mod now[j]=0) then
93 begin
94 if goal[j] div now[j]>max then
95 max:=goal[j] div now[j];
96 end
97 else
98 if (goal[j] div now[j])+1>max then
99 max:=(goal[j] div now[j])+1;
100 end
101 else
102 continue;
103 if not flag then
104 continue
105 else
106 if (max<answer)and(max<>0) then
107 answer:=max;
108 end;
109 end; { main }
110 procedure print;
111 begin
112 if answer=maxlongint>>1 then
113 writeln(-1)
114 else
115 writeln(answer);
116 end; { print }
117 begin
118 previous;
119 init;
120 if m1=1 then
121 writeln(0)
122 else
123 begin
124 main;
125 print;
126 end;
127 end.



posted @ 2012-03-18 18:13  Codinginging  阅读(1131)  评论(0编辑  收藏  举报