如果发现广告等破坏行为,请尽量将条目恢复到较早的版本而不是把相应内容直接删除,谢谢合作。

URAL/1024

来自"NOCOW"

跳转到: 导航, 搜索

做这道题的时候要有一点群论的基础,把给定的置换拆成若干个循环,这个置换的顺序(即k值)就是各个循环的顺序的最小公倍数,各个循环的顺序就是他的长度(即元素个数)(这个在草稿纸上算一下就知道了)。

program cao;
const
  maxn=1000;
 
var
  data,lcm:array[0..maxn] of longint;
  flag:array[0..maxn] of boolean;
  a,b,c,d,e,f,g,h,i,j,k,l,n,m,p,q,ans:longint;
 
function gcd(a,b:longint):longint;
begin
  if b=0 then exit(a);
  exit(gcd(b,a mod b));
end;
 
procedure init;
begin
  read(n);
  for i:=1 to n do
    read(data[i]);
end;
 
procedure main;
begin
  p:=0;
  for i:=1 to n do
    if flag[i]=false then
    begin
      j:=i;
      k:=0;
      while flag[j]=false do
      begin
        inc(k);
        flag[j]:=true;
        j:=data[j];
      end;
      inc(p);
      lcm[p]:=k;
    end;
 
  ans:=1;
  for i:=1 to p do
    ans:=ans*lcm[i] div gcd(ans,lcm[i]);
end;
 
procedure print;
begin
  writeln(ans);
end;
 
begin
  init;
  main;
  print;
end.


LS+1,其实就是所有循环节的最小公倍数。

Program P1024;
 
Var
  n,top                 :       Longint;
  p,lit                 :       Array [1..1000] of Integer;
  use                   :       Array [1..1000] of Boolean;
 
Procedure Init;
  var
    a                   :       Longint;
  begin
    readln(n);
    for a:=1 to n do read(p[a]);readln;
  end;
 
Procedure DFS(tn,sum:Longint);
  begin
    inc(sum);
    use[tn]:=True;
    if use[p[tn]] then begin inc(top);lit[top]:=sum;Exit;end;
    DFS(p[tn],sum);
  end;
 
Procedure Main;
  var
    a                   :       Longint;
  begin
    Fillchar(use,sizeof(use),False);
    for a:=1 to n do
      if not(use[a]) then
        DFS(a,0);
  end;
 
Function gcd(p,q:Longint):Longint;
  begin
    if q=0 then Exit(p);
    Exit(gcd(q,p mod q));
  end;
 
Function GetLcm:Longint;
  var
    a,ans               :       Longint;
  begin
    ans:=lit[1];
    for a:=2 to top do ans:=(ans*lit[a]) Div gcd(ans,lit[a]);
    Exit(ans);
  end;
 
Procedure Print;
  begin
    writeln(GetLcm);
  end;
 
Begin
  Init;
  Main;
  Print;
End.
个人工具