poj 2155 Matrix 二维树状数组

题意:有一个一开始全是0的n*n的矩阵,现有两个操作:一个是把一个子矩阵内的数字全部xor 1,也就是1变0,0变1;一个是输出矩阵内的某个数是0还是1.


分析:

这是我第一次写二维树状数组。

那么二维树状数组的插入操作代码是

  i:=x;
  while i<=n do
  begin
    j:=y;
    while j<=n do
    begin
      a[i,j]:=a[i,j]+delta;
      j:=j+lowbit(j);
    end;
    i:=i+lowbit(i);
  end;   


求和代码:

  i:=x;
  while i>0 do
  begin
    j:=y;
    while j>0 do
    begin
      sum:=sum+a[i,j];
      j:=j-lowbit(j);
    end;
    i:=i-lowbit(i);
  end;

但是这题很显然不能裸着做。

我的方法是:

a[i,j]表示a[i+lowbit(i)-1,j+lowbit(j)-1]到a[i,j]这个矩阵内一共进行了多少次修改操作。

对矩阵(x1,y1)...(x2,y2)进行修改:相当于在(1,1)...(x2,y2)  (1,1)...(x1-1,y2)  (1,1)...(x2,y1-1)  (1,1)...(x1-1,y2-1)这四个矩阵每个矩阵进行一次修改操作。

求(x,y)被进行了多少次操作:相当于求(x,y)...(n,n)内进行了多少次操作。

然后就可以套用二维树状数组来做了。


代码:

var
  n,m,t,l:longint;
  a:array[0..1000,0..1000] of longint;

function lowbit(x:longint):longint;
begin
  lowbit:=x and -x;
end;

procedure updata(x,y:longint);
var
  i,j:longint;
begin
  if (x=0)or(y=0) then exit;
  i:=x;
  while i>0 do
  begin
    j:=y;
    while j>0 do
    begin
      inc(a[i,j]);
      j:=j-lowbit(j);
    end;
    i:=i-lowbit(i);
  end;
end;

function sum(x,y:longint):longint;
var
  i,j:longint;
begin
  if (x=0)or(y=0) then exit(0);
  sum:=0;
  i:=x;
  while i<=n do
  begin
    j:=y;
    while j<=n do
    begin
      sum:=sum+a[i,j];
      j:=j+lowbit(j);
    end;
    i:=i+lowbit(i);
  end;
end;

procedure main;
var
  i,x1,x2,y1,y2,s:longint;
  c:char;
begin
  readln(n,m);
  fillchar(a,sizeof(a),0);
  for i:=1 to m do
  begin
    read(c);
    if c='C'
      then begin
             readln(x1,y1,x2,y2);
             updata(x2,y2);
             updata(x1-1,y2);
             updata(x2,y1-1);
             updata(x1-1,y1-1);
           end
      else begin
             readln(x1,y1);
             s:=sum(x1,y1) mod 2;
             if s=0
               then writeln(0)
               else writeln(1);
           end;
  end;
end;

begin
  readln(t);
  for l:=1 to t do
  begin
    main;
    writeln;
  end;
end.


你可能感兴趣的:(poj 2155 Matrix 二维树状数组)