题意:有一个一开始全是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.