voj 1049 送给圣诞夜的礼品 矩阵快速幂

题目大意:顺次给出m个置换,反复使用这m个置换对初始序列进行操作,问k次置换后的序列。m<=10, k<2^31。

分析:对于每一个置换构造一个n*n的矩阵,然后求出这m个矩阵的乘积记为矩阵A,然后算出A^k div m,再处理下取模后的几个变换就好了。

代码:

type
  arr=array[1..100,1..100] of longint;

var
  n,m,p,i,j,x:longint;
  c,d:arr;
  f:array[1..10] of arr;

procedure chengd(a,b:arr);
var
  i,j,k:longint;
begin
  fillchar(d,sizeof(d),0);
  for i:=1 to n do
    for j:=1 to n do
      for k:=1 to n do
        d[i,j]:=d[i,j]+a[i,k]*b[k,j];
end;

procedure chengc(a,b:arr);
var
  i,j,k:longint;
begin
  fillchar(c,sizeof(c),0);
  for i:=1 to n do
    for j:=1 to n do
      for k:=1 to n do
        c[i,j]:=c[i,j]+a[i,k]*b[k,j];
end;

procedure ksm(x:longint);
begin
  if x=0 then exit;
  ksm(x div 2);
  chengc(c,c);
  if x mod 2=1 then chengc(c,d);
end;

begin
  readln(n,m,p);
  for i:=1 to m do
    for j:=1 to n do
    begin
      read(x);
      f[i,x,j]:=1;
    end;
  for i:=1 to n do
  begin
    d[i,i]:=1;
    c[i,i]:=1;
  end;
  for i:=1 to m do
    chengd(d,f[i]);
  ksm(p div m);
  for i:=1 to p mod m do
    chengc(c,f[i]);
  for i:=1 to n do
    for j:=1 to n do
      if c[j,i]=1 then
      begin
        write(j,' ');
        break;
      end;
end.


你可能感兴趣的:(voj 1049 送给圣诞夜的礼品 矩阵快速幂)