现在的位置: 首页 > 综合 > 正文

poj3150

2018年01月15日 ⁄ 综合 ⁄ 共 988字 ⁄ 字号 评论关闭

【题意】

一个n个位置的环,每经过一次置换,每个位置的值会变成上一次周围d范围之内的和,求mod m后置换过k次后每个位置的值

【输入】

第一行n、m、d、k

第二行n个数,表示n个数的初始值

【输出】

输出n个数表示经过k次置换后,每个位置的值

很容易可以看出是矩阵乘法

n<=500

如果构建n*n的矩阵,矩阵乘法复杂度为n^3,那么总体复杂度为n^3log k 是不能接受的

但是可以发现一个矩阵的性质

因为是求d范围之内之和,所以矩阵每一行基本一样,只是错了一位而已

所以求矩阵的时候只需要求一行就够了,复杂度降到n^2,便可以通过了

program poj3150;
type
  arr=array [0..501] of int64;
var
  d,m,n,i,j,k:longint;
  sum:int64;
  h:array [0..501] of int64;
  ans,root:arr;

function convert (now:longint):longint;
begin
  now:=now mod n;
  if now=0 then exit(n)
           else exit(now);
end;

function multiply (a,b:arr):arr;
var
  i,j,k:longint;
  ans:arr;
begin
  fillchar(ans,sizeof(ans),0);
  for i:=1 to n do
    for j:=1 to n do
      ans[i]:=(ans[i]+a[j]*b[convert(i+j-1)]) mod m;
  exit(ans);
end;

procedure quick (now:longint);
begin
  if now=1 then
    begin
      ans:=root;
      exit;
    end;
  quick(now div 2);
  ans:=multiply(ans,ans);
  if now and 1 = 1 then ans:=multiply(ans,root);
end;

begin
  read(n,m,d,k);
  for i:=1 to n do
    read(h[i]);
  for i:=1 to d+1 do
    root[i]:=1;
  for i:=n-d+1 to n do
    root[i]:=1;
  quick(k);
  for i:=1 to n do
    begin
      sum:=0;
      for j:=1 to n do
        sum:=(sum+h[convert(i+j-1)]*ans[j]) mod m;
      write(sum,' ');
    end;
  writeln;
end.
【上篇】
【下篇】

抱歉!评论已关闭.